useEffect 3가지 사용 패턴
React useEffect의 3가지 사용 패턴에 대해 알아봅니다.
의존성 배열 없는 useEffect
useEffect(() => {
// This runs after every render
})
- 실행 시점: 컴포넌트가 렌더링될 때마다 실행
- 사용 사례: 모든 상태 변화를 추적해야 할 때, DOM 업데이트를 실시간으로 감지해야 할 때
- 주의사항: 너무 자주 실행될 수 있어 성능에 영향을 줄 수 있음, 불필요한 리렌더링을 발생시킬 수 있음, 가능하면 피하는 것이 좋음
빈 의존성 배열이 있는 useEffect
useEffect(() => {
// This runs only on mount
}, [])
- 실행 시점: 컴포넌트가 처음 마운트 된 시점
- 사용 사례: 초기 데이터 페칭, 이벤트 리스너 설정, 외부 API 연결, 타이머 설정
- 주의사항: 클린업 함수를 반환하면 컴포넌트 언마운트 시 실행됨, 서버 사이드 렌더링(SSR)에서는 동작이 다를 수 있음 (web API, data fetching, event listener 등)
의존성 배열이 있는 useEffect
useEffect(() => {
// This runs on mount and when dependencies change
}, [a, b])
- 실행 시점: 컴포넌트 마운트, 의존성 배열의 값이 변경
- 사용 사례: 특정 상태 변화에 따른 부수 효과 처리, API 호출 (특정 값이 변경될 때)
- 주의사항: 의존성 배열에 누락된 의존성이 있으면 버그 발생 가능, 객체나 배열을 의존성으로 사용할 때는 주의 필요, 불필요한 실행을 피하기 위해 메모이제이션 고려
🚧 useEffectEvent (React 18.2 - experimental)
- useCallback
function Page({ url }) {
const { items } = useContext(ShoppingCartContext);
const numberOfItems = items.length;
const onVisit = useCallback((visitedUrl) => {
logVisit(visitedUrl, numberOfItems);
}, [numberOfItems]);
useEffect(() => {
onVisit(url);
}, [url, onVisit]);
...
}
- useEffectEvent
function Page({ url }) {
const { items } = useContext(ShoppingCartContext)
const numberOfItems = items.length
const onVisit = useEffectEvent((visitedUrl) => {
logVisit(visitedUrl, numberOfItems)
})
useEffect(() => {
onVisit(url)
}, [url]) // ✅ All dependencies declared
// ...
}
- 실행 시점: useEffect 내부에서 실행
- 사용 사례: 이벤트 핸들러에서 최신 상태를 항상 안정적으로 참조, useEffect의 과도한 의존성 해결
- 주의사항: useEffect 내부에서만 호출 가능, 다른 컴포넌트나 Hooks에 전달 불가