본문 바로가기

React💃

[React] UseEffect가 두번 실행되는 이유

부트캠프를 할 당시, React를 공부했었다.

그러다가 첫 회사에서는 Vue.js 프레임워크를 사용을 하여 입사하고 지금까지 쭉 Vue로 개발을 하고, 공부를 하고 있다.

 

물론 Vue를 계속 공부하고 있지만, 많은 회사에서는 React를 사용하고 있어서 React도 다시 공부를 해야겠다는 생각이 들어서 조금씩이라도 하고 있다.

 

# 상황

함수 컴포넌트에서 사용하는 Hook 중 하나인 useEffect를 공부하는 와중,

예제를 보고 똑같이 따라하는데도

책에서는 처음 렌더링 시 '한번'만 실행이 되는데 내가 짠 코드에서는 계속 두 번씩 실행이 되는 것이다.

//Info.js
import { useState, useEffect } from 'react';

const Info = () => {
  const [name, setName] = useState('');
  const [nickname, setNickname] = useState('');
  useEffect(() => {
    console.log('렌더링이 완료되었습니다!');
    console.log({ name, nickname });
  });
  
  const onChangeName = (e) => {
   setName(e.target.value);
  };
  
  const onChangeNickname = (e) => {
   setNickname(e.target.value);
  };
  
  return(
   <div>
     <div>
       <input value={name} onChange={onChangeName} />
       <input value={nickname} onChange={onChangeNickname} />
     </div>
     <div>
      <div>
       <b>이름:</b> {name}
      </div>
      <div>
       <b>닉네임:</b> {nickname}
      </div>
     </div>
   </div>
  )
}

export default Info;
//App.js
import Info from './Info';

const App = () => {
  return <Info />;
}

export default App;

두번씩 콘솔이 찍힌다.

첫 렌더링 시에 이렇게 useEffect가 두 번 실행되었다.

 

 

# 원인 파악

왜그런가 찾아보니 범인은 바로...

index.js 파일의 <React.StrictMode>였다.

// index.js
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
 <React.StrictMode>
  <App />
 </React.StrictMode>
);

 

 

## Strict Mode에 관한 공식문서

StrictMode에 대해 React 공식문서를 찾아보면 아래와 같이 나와있다.

 

Strict Mode enables the following checks in development:
Your components will re-render an extra time to find bugs caused by impure rendering.

 

즉, 불완전한 렌더링으로 인한 버그들을 찾기 위해, 컴포넌트를 한번 더 렌더링을 한다.

 

그리고,

짧게 요약해보자면,

추후에 사용자가 탭을 이전/앞으로 이동할 때 이전 페이지를 바로 보여주기위해 이전과 같은 상태를 사용해서 트리를 unmount/remount를 하는 기능을 넣고싶은데,

이렇게 여러번 remount를 할 때마다 같은 화면을 보여주기 위해서, React18버전 이후로는 여러번 마운트됐을 때 문제가 될 수 있는 부분이 있는지 확인할 수 있도록 StrictMode를 제공한다.

 

 

## StrictMode의 특징

- React 18 이상의 버전을 설치한 프로젝트부터 등장한다.

- 개발 모드에서만 활성화 되므로, 빌드가 된 후의 프로젝트에서는 StrictMode는 비활성화된다.

- React.Fragment(<></>)와 같이 UI를 렌더링하지 않는다. 따라서 실제 웹페이지 상으로는 출력되지 않는다.

 

 

# 해결법

가장 간단한 방법은 <React.StrictMode>태그를 제거하는 것!

// index.js
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <App />
);

 

 

* 참고글

- https://thoughtcode.tistory.com/3

 

[React]useEffect가 2번 호출되는 이유(feat. StrictMode)

문제 확인 React 18 버전을 사용하여 애플리케이션 개발을 진행하던 도중 별다른 코드를 작성하지 않았는데 useEffect() 안의 내용이 두 번 출력되는 경우가 발생하였습니다. 이 현상은 개발 시에만

thoughtcode.tistory.com

- https://react.dev/reference/react/StrictMode

 

<StrictMode> – React

The library for web and native user interfaces

react.dev