React 18 RC 업그레이드 후 useEffect 이중 실행 이슈

문제 상황

새해 첫 업무로 React 18 RC 버전 업그레이드를 검토하던 중, 개발 환경에서 API 호출이 두 번씩 발생하는 이슈를 발견했다.

useEffect(() => {
  fetchUserData(userId);
}, [userId]);

로그를 확인해보니 동일한 API가 연속으로 두 번 호출되고 있었다. 프로덕션 빌드에서는 정상 동작했지만, 개발 환경에서만 재현되는 상황이었다.

원인 분석

React 18의 Strict Mode가 강화되면서, 컴포넌트의 mount/unmount/remount 사이클을 의도적으로 시뮬레이션하는 동작이 추가되었다. 이는 향후 추가될 기능(Offscreen API 등)을 대비한 변경사항이다.

기존에는 mount 시점만 체크했다면, 이제는 cleanup 함수가 제대로 구현되어 있는지까지 검증하는 것이다.

해결 방법

AbortController를 사용해 cleanup을 구현했다.

useEffect(() => {
  const controller = new AbortController();
  
  fetchUserData(userId, { signal: controller.signal })
    .catch(err => {
      if (err.name !== 'AbortError') {
        console.error(err);
      }
    });
  
  return () => controller.abort();
}, [userId]);

개발 환경에서는 여전히 두 번 호출되지만, 첫 번째 요청은 적절히 취소되고 두 번째 요청만 완료된다.

소감

Strict Mode의 이 변경은 사이드 이펙트 관리의 중요성을 다시 한번 상기시켜준다. 기존 코드베이스에서 cleanup이 누락된 useEffect들을 찾아 수정하는 작업이 필요할 것 같다. React 18 정식 출시 전에 미리 대응해두면 좋을 것 같다.

React 18 RC 업그레이드 후 useEffect 이중 실행 이슈