왜 Next.js 환경에서 useEffect 가 두번 호출되는 걸까?

이형준·2023년 12월 26일
2

트러블슈팅

목록 보기
5/7
post-thumbnail

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개발 환경에서 어플리케이션을 더 엄격하게 검사하여 예상치 못한 버그를 사전에 찾아내는 데에 도움을 주는 기능이다.

이를 활성화 하게 되면,

  1. 컴포넌트의 불완전한 렌더링을 검사하기 위해, 한 번 더 렌더링된다.

  2. Effect 클린업 함수를 작성하지 않아 발생하는 버그를 검사하기 위해, Effect 들을 한 번 더 실행한다.

  3. 컴포넌트에서 더 이상 사용되지 않는 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 가 한 번만 호출되는 것을 확인할 수 있다.

profile
저의 미약한 재능이 세상을 바꿀 수 있을 거라 믿습니다.

0개의 댓글