웹 개발
useEffect 훅이 예상과 다르게 작동할 때
React에서 useEffect 훅이 무한 루프를 만들거나 제때 실행되지 않을 때의 진단 방법.
React에서 useEffect를 사용할 때 검색해서 복사한 코드를 바로 사용하면, 의존성 배열이 잘못되거나 클로저 문제로 인해 예상과 다르게 작동할 수 있다. 특히 외부 라이브러리나 API 호출을 포함하면 더 복잡해진다.
기본 상황 확인
먼저 어떤 상황에서 문제가 발생하는지 파악한다.
npm run build
로컬에서 빌드가 정상인지 확인한 후, 브라우저 개발자 도구 콘솔에서 에러 메시지를 본다.
무한 루프 진단
useEffect가 계속 실행되어서 네트워크 요청이 반복되거나 상태 업데이트가 무한 반복되는 경우, 대부분 의존성 배열 때문이다.
useEffect(() => {
// 이 코드가 계속 실행됨
console.log('Effect runs');
}, []); // 올바른 의존성 배열
- 의존성 배열이 없으면 매 렌더링마다 실행
- 의존성 배열이
[]이면 마운트할 때만 한 번 실행 - 의존성에 특정 값을 넣으면 그 값이 바뀔 때만 실행
클로저 문제
useEffect 내에서 상태(state)를 사용할 때, 의존성 배열에 그 상태를 넣지 않으면 오래된 값을 참조하게 된다.
useEffect(() => {
const timer = setInterval(() => {
setCount(count + 1); // count가 항상 초기값일 수 있음
}, 1000);
}, []); // count를 의존성에 넣으면 매번 interval이 재생성됨
이벤트 흐름 추적
콘솔 로그를 추가해서 useEffect가 실제로 언제 실행되는지 확인한다.
useEffect(() => {
console.log('Effect: component mounted or dependency changed');
return () => console.log('Cleanup: component will unmount');
}, [/* dependencies */]);
모바일에서도 문제가 나타나는지 확인하면, 환경별 차이를 파악할 수 있다.
흔한 실수들
- async/await를 useEffect에 직접 사용하기
// 틀린 예
useEffect(async () => { ... });
// 올바른 예
useEffect(() => {
const fetchData = async () => { ... };
fetchData();
}, []);
-
렌더링 조건이 애매함 - 특정 상태에서만 문제가 날 수 있음
-
상태 업데이트 후 바로 새로운 상태를 가정 - 상태 업데이트는 비동기
최종 검증
- 각 시나리오별로 useEffect가 제때 실행되고 정리되는지 확인
- 네트워크 탭에서 불필요한 API 호출이 없는지 확인
- 콘솔에서 에러나 경고가 없는지 확인
useEffect의 동작을 완벽히 이해하면 React 개발이 훨씬 수월해진다.