effect는 그 의존성에 따라 재실행되며, 그 배열을 잘못 다루는 것이 React 버그의 1순위 원인입니다.
함정 1: 누락된 의존성 → 오래된 값(stale value)
effect는 생성된 render의 값들을 클로저로 가둡니다. 의존성을 생략하면 오래된 값을 계속 사용합니다:
jsx
( {
id = ( {
.(count);
}, );
(id);
}, []);
effect는 그 의존성에 따라 재실행되며, 그 배열을 잘못 다루는 것이 React 버그의 1순위 원인입니다.
effect는 생성된 render의 값들을 클로저로 가둡니다. 의존성을 생략하면 오래된 값을 계속 사용합니다:
( {
id = ( {
.(count);
}, );
(id);
}, []);
해결: count를 deps에 추가하거나, 그것이 필요 없는 함수형 업데이터를 사용하세요(setCount(c => c + 1)).
객체/배열/함수는 매 render마다 재생성되므로 항상 "새로운" 것이 되어 effect가 안정되지 않습니다:
const options = { id }; // ❌ 매 render마다 새 객체
useEffect(() => { load(options); }, [options]); // 매 render마다 실행
해결: 원시 값([id])에 의존하거나 useMemo/useCallback으로 memoize하세요.
useEffect(() => {
const ctrl = new AbortController();
fetch(url, { signal: ctrl.signal }).then(setData);
return () => ctrl.abort(); // `url`이 변경될 때 이전 요청을 취소
}, [url]);
cleanup이 없으면 느린 이전 요청이 더 새로운 요청 이후에 완료되어 최신 데이터를 덮어쓸 수 있고(경쟁 상태), 구독/타이머가 쌓일 수 있습니다. react-hooks/exhaustive-deps ESLint 규칙이 대부분의 누락된 의존성 사례를 잡아줍니다.
주니어부터 시니어까지 상세한 답변이 포함된 IT 면접 질문 라이브러리.
후원하기