[React] 개발단계에서 컴포넌트가 왜 두번씩 호출될까? (StrictMode)

Seonup·2023년 1월 30일
4

React

목록 보기
1/1

codeSandBox로 react를 공부하는 중에 함수형 컴포넌트를 생성하여 컴포넌트가 몇 번 호출되는지 확인하기 위해 console을 찍어보았더니, 2번씩 찍히는 현상을 발견했다.

문제 코드


// index.js
import React, { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./styles.css";

import App from "./App";

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

state를 props로 전달하는 과정에서 에러가 있는지 확인하기 위해 하위 컴포넌트의 코드를 다르게 작성했다.

  1. 하위 Component에 props로 state를 전달하는 방식
// App.js
import { useState } from "react";

function MyButton(props) {
  // console이 왜 두 번 찍히지?
  console.log(props);
  return <button onClick={props.onClick}>{props.count}</button>;
}

export default function App() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <>
      <h1>Counter</h1>
      <MyButton count={count} onClick={handleClick} />
    </>
  );
}

  1. 하위 컴포넌트가 state를 가지고 있는 방식
// App.js
import { useState } from "react";

function MyButton() {
  const [count, setCount] = useState(0);

  // console이 왜 두 번 찍히지?
  console.log(count, setCount);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <>
      <p>{count}</p>
      <button onClick={handleClick}>click!</button>
      </>
  );
}

export default function App() {
  return (
    <>
      <h1>Counter</h1>
      <MyButton />
    </>
  );
}

CodeSandbox에서 발생하는 것인지 확인하기 위해 Create React App으로 react 애플리케이션을 생성해서 동일한 방식으로 코드를 작성했다. 결과는 codeSandbox와 동일하게 console이 두 번 찍혔다.

🛠 해결


index.js에서 render시 <StrictMode>를 제거하니 콘솔에 기대하던 모습으로 console이 한번만 찍혔다.

🤔 StrictMode는 어떤 녀석일까?


react 함수는 버그를 일으키거나 예측이 불가능할 수 있기 때문에 React는 Strict 모드를 지원한다. <StrictMode></StrictMode> 사이에 react 컴포넌트를 작성하면, 오류 검사하기 위해 렌더링 단계에서 의도적으로 함수를 두 번 호출한다고 한다.

React는 사용자의 상호작용이 일어나지 않으면 렌더링 단계에서 어떠한 결과도 변경되지 않는다. 따라서 StrictMode는 초기 렌더링이 끝난 후 함수를 한번 더 호출하여 결과값에 변화가 있는지 확인하고, 그 변화로 오류를 감지할 수 있다.

To help you find accidentally impure code, Strict Mode calls some of your functions (only the ones that should be pure) twice in development. This includes:

  • Your component function body (only top-level logic, so this doesn’t include code inside event handlers)
  • Functions that you pass to useStateset functions, useMemo, or useReducer
  • Some class component methods like constructorrendershouldComponentUpdate (see the whole list)

Fixing bugs found by double rendering in development - beta.reactjs.org

예를 들어, 순수 함수를 지향하는 React에서 비순수함수로 작성된 컴포넌트가 있다면 Strict Mode가 초기 렌더링이 끝난 이후에 함수를 한번 더 호출하여 동일 컴포넌트임에도 불구하고 반환하는 값이 다르게 나오는 것을 감지 할 수 있다. 순수 함수 검사에 대한 자세한 내용은 React 베타 문서에서 확인할 수 있다.

💡 StrictMode는 개발 환경에서만 이중 호출되고 베포 단계에서는 영향을 끼치지 않으니, 마음 편하게 사용하자. console이 두 번 찍히는 것이 거슬리면 를 제거하면 제거할 수는 있다. 하지만, 개발과정에서 오류를 감지하기 위한 좋은 기능이니 그냥 적용하는 것이 좋은 듯 하다!

profile
박선우

0개의 댓글