Next.js로 개발을 하다가 이상한 현상을 하나 발견했다. 분명히 컴포넌트가 한 번만 마운트될 거라 생각했는데, 콘솔에 로그가 세 번이나 찍힌 것이다.
상황
다음은 테스트로 작성했던 코드다.
const q1 = useTestDataQuery(1, { enabled: false });
const q2 = useTestDataQuery(2, { enabled: false });
useEffect(() => {
// onMount -> 추후 q1 대신 GET 호출 예정
q1.refetch();
return () => {
// onUnmount -> 추후 q2 대신 POST 호출 예정
q2.refetch();
};
}, []);
단순히 마운트될 때 1번, 언마운트될 때 1번만 호출될 거라 예상했지만, 개발 모드 콘솔에는 아래처럼 로그 찍혔다.
[React Mount] q1.refetch() 실행
[React Unmount] q2.refetch() 실행
[React Re-mount] q1.refetch() 실행
즉, 컴포넌트가 한 번만 마운트되는 것이 아니라 마운트 → 언마운트 → 리마운트되는 동작이 발생한 것이다.
왜 이렇게 된 걸까?
이 현상은 React의 버그가 아니라 React 18부터 추가된 Strict Mode 동작 때문이다. React 18부터는 개발 모드에서 Strict Mode가 effect가 여러 번 실행되고 정리되는 상황을 일부러 시뮬레이션해서, 컴포넌트가 향후 Reusable State 기능(상태 보존 리마운트)에 대비할 수 있도록 도와주는 역할을 하고 있다. (이 동작은 개발 모드(Development Mode) 에서만 발생한다.)
왜 이렇게 하냐면!
React 팀은 앞으로 나올 Reusable State (상태 재사용) 기능을 대비하고 있다. 이 기능은 컴포넌트를 완전히 파괴하지 않고 상태를 유지한 채로 다시 마운트할 수 있게 만드는 기능이다.
예를 들어 탭 전환이나 Suspense 로딩 전환 시 기존 상태를 그대로 유지한 채 컴포넌트를 복구하는 구조다.
이를 제대로 지원하려면 모든 useEffect가 “깨끗하게 정리(cleanup)”되고 다시 실행되더라도 부작용이 없어야 한다. 그래서 React는 개발 모드에서 의도적으로 마운트/언마운트를 두 번 반복하며 문제가 없는지 테스트한다.
Next.js에서는 기본적으로 활성화되어 있다
Next.js의 next.config.js에는 기본적으로 다음 설정이 들어가 있다. 그래서 Next.js로 개발하면 React의 Strict Mode 시뮬레이션이 항상 동작한다.
module.exports = {
reactStrictMode: true,
};
이 옵션을 false로 설정하면, 로그는 한번만 찍히지만 React가 제공하는 조기 버그 감지 기능을 잃게 된다. production 모드로 실행했을 때는 정상 동작하기 때문에, 문제라고 생각했던 부분의 원인을 알고 개발을 진행하면 될 것 같다.
'Next' 카테고리의 다른 글
| mutateAsync 도입기 (0) | 2025.11.14 |
|---|---|
| Next.js 프로젝트 구조, src/app으로 써야 할까? (0) | 2025.10.19 |
| Loading.jsx와 Suspense fallback의 차이 (0) | 2025.07.01 |
| bodySizeLimit 설정 (0) | 2025.06.16 |