왜 useEffect가 두 번씩 실행될까?

오늘은 왜 개발환경에서 useEffect가 두 번씩 호출되는지 알아보겠습니다.

useEffect가 두 번씩 호출되는 예시

프론트엔드 개발자 대부분은 프로젝트를 진행하면서 useEffect안에 console.log() 코드를 한 번 씩 적어서 테스트해보신 적이 있을 것 같은데요.
 
저의 경우엔 유저가 사이트에 접속했을 때 useEffect안에 API 호출 코드를 넣어서 방문자 수를 증가시키는 로직을 구현했습니다.
하지만 개발환경에서 테스트해보았을 때 1을 증가시키는게 아닌 로직이 두 번 실행되어 2를 증가하는 상황이 발생했습니다.
분명 dependency array로 빈배열을 사용했고 useRef()를 활용해서 한 번만 실행되게 해놓았는데도 말입니다.
 
위 코드처럼 컴포넌트 마운트 시 로그를 출력하게 한 뒤 확인을 해보면
 
notion image
두 번 실행이 되는 것을 확인할 수 있었습니다.
 

두 번 실행되는 이유는 무엇이었을까

결론부터 말씀드리자면 react 18 버전에서 도입된 strict mode에 의해서 발생이됩니다.
strict mode는 개발 환경에서 어플리케이션을 더 엄격하게 검사하여 예상치 못한 버그를 사전에 찾아내는데 도움을 주는 기능입니다.
 
strict mode를 활성화하게 되면 다음과 같이 동작합니다
  1. 컴포넌트의 불완전한 렌더링을 검사하기 위해, 한 번 더 렌더링됩니다
  1. useEffect의 클린업 함수를 작성하지 않아 발생하는 버그를 검사하기 위해, useEffect들을 한 번 더 실행합니다
  1. 컴포넌트에서 더 이상 사용되지 않는 API를 사용하는지 검사합니다.
 

해결 방법

 
nextjs 프로젝트의 경우 위와 같이 next.config.js 파일에서 reactStrictMode:true로 설정되어 있는 것을 알 수 있습니다. 당연히 false로 변경하면 2번 호출되는 문제가 발생하지 않겠지만 저는 다음의 이유로 false 처리를 하지 않았습니다.
  • strict mode는 개발 환경에서만 동작하고, 배포 환경에서는 동작하지 않는다.
  • strict mode는 예기치 못한 버그들을 찾아내는데에 도움을 준다.
 
따라서, 개발상황에서 필수적으로 해당 문제를 해결해야하는 상황이 아니라면 굳이 strict mode를 비활성화 하지 않아도 될 것 같습니다.