728x90
React에서 Firebase를 사용할 때 발생하는 문제
React와 Firebase를 연동하여 메뉴 관리 시스템을 구현할 때, 종종 화면이 깜빡이거나 스크롤이 초기화되는 문제가 발생한다. 이는 컴포넌트가 불필요하게 리렌더링되거나, Firebase에서 데이터를 불러오는 과정에서 useEffect가 과도하게 실행되기 때문이다. 본 글에서는 이러한 문제를 해결하는 방법을 상세히 설명한다.
문제 분석
1. 화면이 깜빡이고 스크롤이 초기화되는 현상
원인:
- useEffect 내부에서 loadMenuItems()를 호출하여 상태(setMenuItems())를 업데이트함.
- 상태가 변경될 때마다 컴포넌트가 리렌더링되며, 스크롤 위치가 초기화됨.
- useEffect가 의존성 배열 없이 정의되어 있어, 데이터 변경 시마다 불필요하게 실행됨.
해결책:
- useRef를 사용하여 useEffect가 최초 마운트 시에만 실행되도록 변경.
- 데이터 변경 시 전체 목록을 다시 불러오는 것이 아니라, 변경된 데이터만 업데이트하도록 개선.
2. 불필요한 전체 리스트 리렌더링 문제
원인:
- menuItems 상태가 변경될 때마다 전체 리스트가 다시 렌더링됨.
- MenuItemCard 컴포넌트가 React.memo로 감싸져 있지만, onDelete, onAddOption, onDeleteOption 함수가 매번 새로 생성되기 때문에 props가 변경되어 React.memo의 최적화 효과가 사라짐.
해결책:
- useCallback을 사용하여 함수가 재생성되지 않도록 개선.
- 개별 아이템의 상태만 변경하고, 전체 리스트를 다시 불러오는 것을 방지.
3. Firebase 데이터 업데이트 방식 비효율 문제
문제점:
- addOption과 handleDeleteOption에서 loadMenuItems()를 호출하여 전체 데이터를 다시 불러옴.
- Firebase에서 데이터를 불러오는 과정에서 네트워크 트래픽이 증가하고, UI 성능이 저하됨.
해결책:
- Firestore에서 특정 문서만 업데이트하도록 updateDoc을 활용.
- menuItems 상태에서 변경된 데이터만 업데이트하여 UI의 불필요한 리렌더링을 방지.
최적화된 코드
1. useEffect 최적화
const isMounted = useRef(false);
useEffect(() => {
if (!isMounted.current) {
loadMenuItems();
isMounted.current = true;
}
}, []);
설명:
- isMounted라는 useRef 변수를 사용하여, useEffect가 첫 번째 렌더링에서만 실행되도록 제한.
- 불필요한 데이터 요청을 방지하여 성능을 향상시킴.
2. 함수 재생성을 방지하는 useCallback 적용
const handleDeleteItem = useCallback(async (itemId: string) => {
await deleteMenuItem(itemId);
setMenuItems((prev) => prev.filter((item) => item.id !== itemId));
}, [deleteMenuItem]);
설명:
- useCallback을 사용하여 handleDeleteItem 함수가 필요할 때만 재생성되도록 함.
- 이를 통해 React.memo가 적용된 MenuItemCard의 불필요한 리렌더링을 방지.
3. Firebase 데이터 업데이트 최적화
const addOption = useCallback(async (itemId: string, option: Option) => {
const itemRef = doc(db, "menu", itemId);
await updateDoc(itemRef, {
options: [...menuItems.find((item) => item.id === itemId)?.options || [], option],
});
setMenuItems((prev) =>
prev.map((item) =>
item.id === itemId ? { ...item, options: [...(item.options || []), option] } : item
)
);
}, [menuItems]);
설명:
- updateDoc을 사용하여 Firestore의 특정 문서만 업데이트.
- 상태를 직접 수정하여 전체 데이터를 다시 불러오지 않음.
- UI 리렌더링을 최소화하여 성능을 개선.
결론
Firebase와 React를 함께 사용할 때, 불필요한 리렌더링을 최소화하고 성능을 최적화하는 것이 중요하다. 본 글에서 소개한 방법을 적용하면, 데이터 업데이트 시 화면 깜빡임 없이 부드럽게 UI가 유지될 수 있다. 특히 useEffect, useCallback, useRef를 적절히 활용하면, Firebase와의 연동 성능을 크게 향상시킬 수 있다.
728x90
'오류확인.해결' 카테고리의 다른 글
anaconda prompt error : UnicodeEncodeError, libmamba not recognized. (0) | 2024.07.18 |
---|---|
경진대회 준비 (1) | 2024.06.02 |
intellij에서 gitlab repository push 오류 (1) | 2024.04.20 |
gradle 오류 (0) | 2024.04.18 |
Current request is not of type [org.springframework.web.multipart.MultipartRequest] (0) | 2024.04.16 |