수요일

React useEffect 무한루프 — 의존성 배열 검증과 최적화 전략

🔍 검색 키워드: React useEffect 무한루프, useEffect 의존성 배열, React hooks 성능, useEffect 무한 재렌더링, React 성능 최적화

useEffect를 사용하다 보면 컴포넌트가 계속 리렌더링되는 악몽을 경험한다. 브라우저 개발자 도구를 열어보면 콘솔에 로그가 끝없이 출력되고, 네트워크 요청이 수십 개씩 날아간다. 이게 바로 useEffect 무한루프다.

■ 증상

Warning: An effect caused a component to suspend while rendering
또는
컴포넌트가 재렌더링 → useEffect 실행 → state 업데이트 → 다시 재렌더링

■ 원인

1. 의존성 배열 누락 - 의존성 배열을 쓰지 않으면 매 렌더링마다 실행
2. 배열 참조 문제 - 객체나 배열을 의존성에 넣으면 매번 새로운 참조 생성
3. state 업데이트 - useEffect 내에서 의존성에 포함된 state를 업데이트

■ 해결방법

❌ 잘못된 코드:

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetch(`/api/users/${userId}`)
      .then(r => r.json())
      .then(data => setUser(data));
    // 의존성 배열이 없다!
  });
}

✅ 올바른 코드:

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetch(`/api/users/${userId}`)
      .then(r => r.json())
      .then(data => setUser(data));
  }, [userId]); // userId가 변할 때만 실행
}

참조 문제 해결:

function SearchResults({ filters }) {
  const [results, setResults] = useState([]);

  useEffect(() => {
    searchAPI(filters);
  }, [JSON.stringify(filters)]);
}

■ 정리표

의존성 배열 없음 → 매 렌더링마다 실행 → [] 추가하거나 필요한 의존성 명시
배열/객체 의존성 → 참조가 매번 변함 → JSON.stringify() 또는 useMemo()
state 순환 업데이트 → useEffect가 의존성 state 업데이트 → 의존성에서 제외하거나 조건 분기
클로저 문제 → 예전 state 값 참조 → useCallback, useRef 활용

댓글 없음:

댓글 쓰기