useEffect 두 번 발생 트러블 슈팅

Ryomi·2024년 7월 23일
post-thumbnail

소개

React를 사용하다 보면 useEffect 훅이 예상치 않게 두 번 실행되는 현상을 마주칠 수 있습니다.
특히 초기 렌더링 시 useEffect가 두 번 실행되는 문제는 개발 과정에서 혼란을 야기할 수 있습니다.
이번 포스트에서는 이 문제의 원인과 해결 방법에 대해 살펴보겠습니다.
특히, React의 Strict Mode가 이 현상에 어떻게 관여하는지 중점적으로 설명하겠습니다.

문제 상황

useEffect의 deps를 빈 배열로 두었음에도 불구하고, 두 번 이상 연속으로 실행되는 경우는 다음 세 가지 원인 중 하나일 수 있습니다.

  • 해당 컴포넌트가 페이지 내에서 두 번 이상 사용되는 경우
  • 상위 트리에서 언마운트 혹은 리마운트가 발생하는 경우
  • Strict Mode를 사용한 경우

이번 포스트에서는 세 번째 원인, Strict Mode에 대해 자세히 다루겠습니다.

React Strict Mode란?

React Strict Mode는 개발 단계에서 잠재적인 문제를 식별하고 예기치 못한 오류를 예방하기 위해 사용됩니다. Strict Mode는 다음과 같은 생명주기 메소드들과 render, constructor, setState 등을 두 번씩 호출합니다.

  • componentDidMount
  • componentDidUpdate
  • useEffect

이는 실제 배포 환경에서는 발생하지 않으며, 개발 단계에서만 해당됩니다. 따라서, Strict Mode는 실제 동작에는 영향을 미치지 않지만, 개발 중에는 useEffect가 두 번 실행되는 문제를 일으킬 수 있다고 합니다.

에러 예시 코드

다음은 useEffect가 두 번 실행되는 현상을 보여주는 예시 코드입니다:


import React, { useEffect, useState } from 'react';

const MyComponent = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log('useEffect called');
    // 여기서 데이터를 가져오 작업을 수행할 수 있습니다.
  }, []);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};
export default MyComponent;

이 코드를 실행하면 useEffect가 두 번 호출되는 것을 콘솔에서 확인할 수 있습니다.

해결 방법

Strict Mode는 개발 단계에서만 적용되기 때문에 실제 배포 시에는 문제가 되지 않지만, 개발 단계에서 초기 렌더링 중복 발생을 방지하려면 임시로 StrictMode를 비활성화할 수 있는 방법 즉, index.js 파일에서 <React.StrictMode> 컴포넌트를 주석 처리하는 방법으로 useEffect의 중복 발생을 방지할 수 있습니다.

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

// Strict Mode 주석 처리
ReactDOM.render(
  // <React.StrictMode>
  <App />,
  // </React.StrictMode>,
  document.getElementById('root')
);

이렇게 하면 useEffect가 한 번만 실행됩니다. 하지만 Strict Mode는 유용한 디버깅 도구이기때문에, 문제를 해결한 후에는 다시 활성화하는 것이 좋습니다.

결론

React Strict Mode는 좋은 디버깅 도구이나 useEffect가 두 번 실행되는 현상을 초래할 수 있습니다. 이 문제를 해결하기 위해 개발 단계에서는 임시로 Strict Mode를 비활성화할 수 있습니다.

profile
making a list, checking it twice 🐥

0개의 댓글