useEffect
!
리액트를 이용하여 작업해 본 경험이 있는 프론트엔드 엔지니어라면 너무나 친숙할 hook
이다. 컴포넌트 내에서 API 호출, 로컬 스토리지 접근 등 일반적인 리액트의 렌더링 주기를 벗어난 동작을 하는 데에 사용되는 아주 유용한 훅이다.
가장 흔하게 사용되는 사용법은 컴포넌트 마운트 시 API를 호출하여 컴포넌트에서 필요한 데이터들을 가져오는 건데, Next.js
에서 사용해보면 뭔가 신기한 현상을 만나볼 수 있다.
"use client";
import { useEffect } from "react";
export default function Home() {
useEffect(() => {
console.log("useEffect called");
}, []);
return <main>useEffect test</main>;
}
위처럼 컴포넌트 마운트 시 콘솔에 로그를 출력하는 간단한 컴포넌트를 작성하고, 해당 컴포넌트를 렌더링 해 보면..
useEffect
가 두 번 호출된다?
해당 이슈는 React 18
에서 도입된 strict mode
기능에 의해 발생한다. Next.js
의 개발 환경에서는 이 stirct mode
가 활성화되어 있다.
그렇다면, strict mode
가 뭘까?
strict mode
는 개발 환경에서 어플리케이션을 더 엄격하게 검사하여 예상치 못한 버그를 사전에 찾아내는 데에 도움을 주는 기능이다.
이를 활성화 하게 되면,
컴포넌트의 불완전한 렌더링을 검사하기 위해, 한 번 더 렌더링된다.
Effect
클린업 함수를 작성하지 않아 발생하는 버그를 검사하기 위해, Effect
들을 한 번 더 실행한다.
컴포넌트에서 더 이상 사용되지 않는 API
를 사용하는 지 검사한다.
우리가 주목할 부분은 2번.
해당 이슈가 발생한 원인이 strict mode
때문임을 알 수 있다.
strict mode
가 이 문제를 발생시키는 것을 알았으니, 이를 설정을 통해 비활성화하여 문제를 간단하게 해결할 수 있다.
다만 비활성화 전 유의해야할 점이 몇 가지 있다.
우선, strict mode
는 개발 환경에서만 동작하고, 프로덕트 배포 환경에서는 동작하지 않는다.
또한, strict mode
는 상술했듯 예기치 못한 버그들을 찾아내는 데에 도움을 준다.
따라서, 개발 환경에서 필수적으로 해당 문제를 해결해야 하는 상황이 아니라면, 굳이 strict mode
를 비활성화 할 필요는 없다. 어차피 배포 환경에서는 원하는 대로 Effect
가 한 번만 호출될테니까!
// next.config.js
const nextConfig = {
reactStrictMode: false,
};
module.exports = nextConfig;
Next.js
프로젝트 최상위의 next.config.js
파일을 위와 같이 수정하면 비활성화 끝!원하는 동작대로 useEffect
가 한 번만 호출되는 것을 확인할 수 있다.