<StrictMode> lets you find common bugs in your components early during development. <StrictMode>를 사용하면 개발 중에 컴포넌트에서 흔히 발생하는 버그를 조기에 발견할 수 있습니다.

<StrictMode>
<App />
</StrictMode>

Reference참조

<StrictMode>

Use StrictMode to enable additional development behaviors and warnings for the component tree inside: StrictMode를 사용하여 내부의 컴포넌트 트리에 대한 추가 개발 동작 및 경고를 활성화 하세요:

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';

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

See more examples below. 아래에서 더 많은 예시를 확인하세요.

Strict Mode enables the following development-only behaviors: Strict Mode 는 다음과 같은 개발 전용 동작을 활성화합니다:

Props

StrictMode accepts no props. StrictMode는 props를 허용하지 않습니다.

Caveats주의사항

  • There is no way to opt out of Strict Mode inside a tree wrapped in <StrictMode>. This gives you confidence that all components inside <StrictMode> are checked. If two teams working on a product disagree whether they find the checks valuable, they need to either reach consensus or move <StrictMode> down in the tree. <StrictMode>로 감싼 트리 내부에서 Strict 모드를 해제할 수 있는 방법은 없습니다. 이로써 <StrictMode> 내의 모든 컴포넌트가 검사된다는 확신을 가질 수 있습니다. 하나의 제품을 작업하는 두 팀이 검사의 가치에 대해 의견이 다를 경우, 합의를 하거나, <StrictMode>를 트리에서 아래로 이동해야 할 것입니다.

Usage사용법

Enabling Strict Mode for entire app전체 앱에 대한 Strict Mode 사용하기

Strict Mode enables extra development-only checks for the entire component tree inside the <StrictMode> component. These checks help you find common bugs in your components early in the development process. Strict Mode를 사용하면 <StrictMode> 컴포넌트 내부의 전체 컴포넌트 트리에 대해 개발 전용 검사를 추가로 수행하게 됩니다. 이 검사를 통해 개발 프로세스 초기에 컴포넌트의 일반적인 버그를 발견할 수 있습니다.

To enable Strict Mode for your entire app, wrap your root component with <StrictMode> when you render it: 전체 앱에 Strict Mode를 사용하려면 렌더링할 때 루트 컴포넌트를 <StrictMode>로 감싸세요:

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';

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

We recommend wrapping your entire app in Strict Mode, especially for newly created apps. If you use a framework that calls createRoot for you, check its documentation for how to enable Strict Mode. 특히 새로 만든 앱의 경우 전체 앱을 Strict Mode로 감싸는 것이 좋습니다. createRoot를 대신 호출하는 프레임워크를 사용하는 경우 해당 프레임워크의 설명서를 참조하여 Strict Mode를 활성화 하는 방법을 확인해보세요.

Although the Strict Mode checks only run in development, they help you find bugs that already exist in your code but can be tricky to reliably reproduce in production. Strict Mode lets you fix bugs before your users report them. 비록 Strict Mode는 개발 환경에서만 실행되지만, 상용 환경에서 재현하기 까다로운 (이미 존재하는) 버그를 찾는 데에도 도움이 됩니다. Strict Mode를 사용하면 사용자가 버그를 신고하기 전에 수정할 수 있습니다.

Note

Strict Mode enables the following checks in development: Strict Mode는 개발 환경에서 다음과 같은 점검을 합니다:

All of these checks are development-only and do not impact the production build. 이러한 모든 검사는 개발 환경 전용이며 상용 빌드에는 영향을 미치지 않습니다.


Enabling Strict Mode for a part of the app앱의 일부에 Strict Mode 사용 설정하기

You can also enable Strict Mode for any part of your application: 애플리케이션의 어떤 부분에 대해서든 Strict Mode를 활성화 할 수 있습니다:

import { StrictMode } from 'react';

function App() {
return (
<>
<Header />
<StrictMode>
<main>
<Sidebar />
<Content />
</main>
</StrictMode>
<Footer />
</>
);
}

In this example, Strict Mode checks will not run against the Header and Footer components. However, they will run on Sidebar and Content, as well as all of the components inside them, no matter how deep. 이 예제에서는 HeaderFooter 컴포넌트에 대해서는 Strict Mode 검사가 실행되지 않습니다. 반면 SidebarContent 및 그 안에 있는 모든 컴포넌트들은 아무리 깊어도 검사가 실행됩니다.


Fixing bugs found by double rendering in development개발환경에서 이중 렌더링으로 발견된 버그 수정하기

React assumes that every component you write is a pure function. This means that React components you write must always return the same JSX given the same inputs (props, state, and context). React는 작성하는 모든 컴포넌트가 순수한 함수라고 가정합니다. 즉, 작성하는 React 컴포넌트는 동일한 입력(props, state, context)이 주어졌을 때 항상 동일한 JSX를 반환해야 합니다.

Components breaking this rule behave unpredictably and cause bugs. 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: 이 규칙을 위반하는 컴포넌트는 예측할 수 없는 동작을 하고 버그를 유발합니다. Strict Mode는 개발 환경에서 실수로 작성한 불순한 코드를 찾을 수 있도록 다음의 일부 함수(순수 함수만)를 두 번 호출합니다:

If a function is pure, running it twice does not change its behavior because a pure function produces the same result every time. However, if a function is impure (for example, it mutates the data it receives), running it twice tends to be noticeable (that’s what makes it impure!) This helps you spot and fix the bug early. 순수 함수는 매번 동일한 결과를 생성하므로 함수를 두 번 실행해도 동작이 변경되지 않습니다. 그러나 함수가 순수하지 않은 경우 (예를 들어, 수신하는 데이터를 변조하는 경우) 순수하지 않은 코드를 두 번 실행하면 눈에 띄는 경향이 있습니다 (그래서 순수하지 않는 것 입니다!) 이를 통해 버그를 조기에 발견하고 수정하는데 도움이 됩니다.

Here is an example to illustrate how double rendering in Strict Mode helps you find bugs early. 다음은 Strict Mode에서 이중 렌더링이 버그를 조기에 발견하는 데 어떻게 도움이 되는지 설명하는 예시입니다.

This StoryTray component takes an array of stories and adds one last “Create Story” item at the end: StoryTray 컴포넌트는 stories 배열을 가져와 마지막에 “Create Story” 항목을 하나 더 추가합니다.

export default function StoryTray({ stories }) {
  const items = stories;
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul>
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

There is a mistake in the code above. However, it is easy to miss because the initial output appears correct. 위의 코드에는 실수가 있습니다. 그러나 초기 출력은 올바르게 나타나기 때문에 놓치기 쉽습니다.

This mistake will become more noticeable if the StoryTray component re-renders multiple times. For example, let’s make the StoryTray re-render with a different background color whenever you hover over it: StoryTray 컴포넌트가 여러 번 다시 렌더링하는 경우 이 실수는 더욱 두드러집니다. 예를 들어, StoryTray 에 포인터를 가져다 놓을 때마다 다른 배경색으로 다시 렌더링되도록 해보겠습니다:

import { useState } from 'react';

export default function StoryTray({ stories }) {
  const [isHover, setIsHover] = useState(false);
  const items = stories;
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul
      onPointerEnter={() => setIsHover(true)}
      onPointerLeave={() => setIsHover(false)}
      style={{
        backgroundColor: isHover ? '#ddd' : '#fff'
      }}
    >
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

Notice how every time you hover over the StoryTray component, “Create Story” gets added to the list again. The intention of the code was to add it once at the end. But StoryTray directly modifies the stories array from the props. Every time StoryTray renders, it adds “Create Story” again at the end of the same array. In other words, StoryTray is not a pure function—running it multiple times produces different results. StoryTray 컴포넌트 위로 마우스를 가져갈 때마다 Create Story가 목록에 다시 추가되는 것을 확인할 수 있습니다. 코드의 의도는 마지막에 한 번만 추가하는 것이었습니다. 하지만 StoryTraystories 배열을 직접 수정합니다. StoryTray는 렌더링할 때마다 동일한 배열의 끝에 Create Story를 다시 추가합니다. 즉, StoryTray는 여러 번 실행하면 다른 결과가 나오는 불순한 함수입니다.

To fix this problem, you can make a copy of the array, and modify that copy instead of the original one: 이 문제를 해결하려면 배열의 복사본을 만든 다음 원본 대신 해당 복사본을 수정하면 됩니다:

export default function StoryTray({ stories }) {
const items = stories.slice(); // Clone the array
// ✅ Good: Pushing into a new array
items.push({ id: 'create', label: 'Create Story' });

This would make the StoryTray function pure. Each time it is called, it would only modify a new copy of the array, and would not affect any external objects or variables. This solves the bug, but you had to make the component re-render more often before it became obvious that something is wrong with its behavior. 이렇게하면 StoryTray 함수가 순수해집니다. 이 함수를 호출할 때마다 배열의 새 복사본만 수정하고 외부 객체나 변수에 영향을 미치지 않습니다. 이렇게 하면 버그는 해결되지만, 컴포넌트의 동작에 문제가 있다는 것이 분명해지기 전까지는 컴포넌트를 더 자주 리렌더링해야 한다는 점에 유의하세요.

In the original example, the bug wasn’t obvious. Now let’s wrap the original (buggy) code in <StrictMode>: 원래 예제에서는 버그가 명확하지 않았습니다. 이제 원래의 (버그가 존재하는) 코드를 <StrictMode>로 래핑해 보겠습니다.

export default function StoryTray({ stories }) {
  const items = stories;
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul>
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

Strict Mode always calls your rendering function twice, so you can see the mistake right away (“Create Story” appears twice). This lets you notice such mistakes early in the process. When you fix your component to render in Strict Mode, you also fix many possible future production bugs like the hover functionality from before: Strict Mode는 항상 렌더링 함수를 두 번 호출 하므로 실수를 바로 확인할 수 있습니다. (예제에서는 “Create Story”가 두 번 표시 됨) Strict Mode를 사용하면 이런 실수를 프로세스 초기 단계에서 발견할 수 있습니다. 컴포넌트가 Strict Mode에서 렌더링되도록 수정하면 이전의 hover 기능과 같이 향후 발생할 수 있는 많은 상용 버그도 함께 수정됩니다.

import { useState } from 'react';

export default function StoryTray({ stories }) {
  const [isHover, setIsHover] = useState(false);
  const items = stories.slice(); // Clone the array
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul
      onPointerEnter={() => setIsHover(true)}
      onPointerLeave={() => setIsHover(false)}
      style={{
        backgroundColor: isHover ? '#ddd' : '#fff'
      }}
    >
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

Without Strict Mode, it was easy to miss the bug until you added more re-renders. Strict Mode made the same bug appear right away. Strict Mode helps you find bugs before you push them to your team and to your users. Strict Mode가 없으면 리렌더링이 되기 전까지 버그를 놓치기 쉬웠습니다. Strict Mode를 사용하면 동일한 버그가 즉시 나타납니다. Strict Mode를 사용하면 버그를 팀과 사용자에게 노출하기 전에 버그를 찾을 수 있습니다.

Read more about keeping components pure. 컴포넌트를 순수하게 유지하는 방법에 대해 자세히 알아보세요.

Note

If you have React DevTools installed, any console.log calls during the second render call will appear slightly dimmed. React DevTools also offers a setting (off by default) to suppress them completely. React DevTools를 설치한 경우 두 번째 렌더링 호출중 console.log 호출이 불분명하게 표시됩니다. React DevTools는 이를 완전히 억제하는 설정도 제공합니다. (기본적으로 꺼져있습니다.)


Fixing bugs found by re-running Effects in development개발 환경에서 Effect를 재실행하여 발견된 버그 수정하기

Strict Mode can also help find bugs in Effects. Strict Mode는 Effect의 버그를 찾는 데에도 도움이 될 수 있습니다.

Every Effect has some setup code and may have some cleanup code. Normally, React calls setup when the component mounts (is added to the screen) and calls cleanup when the component unmounts (is removed from the screen). React then calls cleanup and setup again if its dependencies changed since the last render. 모든 Effect에는 셋업 코드가 있으며 클린업 코드도 있을 수 있습니다. 일반적으로 React는 컴포넌트가 마운트될 때 (화면에 추가될 때) 셋업을 호출하고, 컴포넌트가 마운트 해제될 때 (화면에서 제거될 때) 클린업을 호출합니다.

When Strict Mode is on, React will also run one extra setup+cleanup cycle in development for every Effect. This may feel surprising, but it helps reveal subtle bugs that are hard to catch manually. Strict Mode가 켜져있으면 React는 개발 환경에서 모든 Effect에 대해 셋업 + 클린업 사이클을 한 번 더 실행합니다. 이것을 의아하게 여길 수도 있지만, 수동으로 잡기 어려운 미묘한 버그를 발견하는 데 도움이 됩니다.

Here is an example to illustrate how re-running Effects in Strict Mode helps you find bugs early. 다음은 Strict Mode에서 Effect를 다시 실행하면 버그를 조기에 발견하는 데 어떻게 도움이 되는지 보여주는 예시입니다.

Consider this example that connects a component to a chat: 컴포넌트를 채팅에 연결하는 상황을 살펴봅시다:

import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

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

There is an issue with this code, but it might not be immediately clear. 이 코드에는 문제가 있지만 지금 당장은 명확하지 않을 수 있습니다.

To make the issue more obvious, let’s implement a feature. In the example below, roomId is not hardcoded. Instead, the user can select the roomId that they want to connect to from a dropdown. Click “Open chat” and then select different chat rooms one by one. Keep track of the number of active connections in the console: 문제를 더 명확히 하기 위해 기능을 구현해 보겠습니다. 아래 예제에서는 roomId 가 하드코딩되어 있지 않습니다. 대신 사용자는 드롭다운에서 연결하려는 roomId를 선택할 수 있습니다. “Open chat”을 클릭한 다음 다른 대화방을 하나씩 선택합니다. 콘솔에서 활성화된 연결 수를 추적합니다:

import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

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

You’ll notice that the number of open connections always keeps growing. In a real app, this would cause performance and network problems. The issue is that your Effect is missing a cleanup function: 열려 있는 연결 수가 항상 증가하는 것을 알 수 있습니다. 실제 앱에서는 성능 및 네트워크 문제가 발생할 수 있습니다. 원인은 Effect에 클린업 함수가 없다는 것입니다:

useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => connection.disconnect();
}, [roomId]);

Now that your Effect “cleans up” after itself and destroys the outdated connections, the leak is solved. However, notice that the problem did not become visible until you’ve added more features (the select box). 이제 Effect가 자체적으로 “클린업”되어 오래된 연결을 해제하므로 누수가 해결되었습니다. 그러나 더 많은 기능(셀렉트 박스)을 추가하기 전까지는 문제가 즉시 표시되지 않는다는 점에 유의하세요.

In the original example, the bug wasn’t obvious. Now let’s wrap the original (buggy) code in <StrictMode>: 원래 예제에서는 버그가 분명하지 않았습니다. 이제 원래의 (버그가 있는) 코드를 <StrictMode>로 감싸보겠습니다.

import { 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>
);

With Strict Mode, you immediately see that there is a problem (the number of active connections jumps to 2). Strict Mode runs an extra setup+cleanup cycle for every Effect. This Effect has no cleanup logic, so it creates an extra connection but doesn’t destroy it. This is a hint that you’re missing a cleanup function. Strict Mode를 사용하면 문제가 있음을 즉시 알 수 있습니다 (활성화된 연결 수가 2로 점프합니다). 이는 Strict Mode가 모든 Effect에 대해 셋업 + 클린업 사이클을 실행하기 때문입니다. 이 Effect에는 클린업 로직이 없으므로 추가 연결을 생성하지만 해제하지는 않습니다. 이것은 클린업 함수가 누락되었다는 힌트입니다.

Strict Mode lets you notice such mistakes early in the process. When you fix your Effect by adding a cleanup function in Strict Mode, you also fix many possible future production bugs like the select box from before: Strict Mode를 사용하면 이런 실수를 프로세스 초기에 발견할 수 있습니다. Strict Mode에서 클린업 함수를 추가하여 Effect를 수정하면 이전의 셀렉트 박스와 같이 향후 발생할 수 있는 많은 상용 버그도 함께 수정됩니다:

import { 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>
);

Notice how the active connection count in the console doesn’t keep growing anymore. 콘솔의 활성 연결 수가 더 이상 증가하지 않는 것을 확인할 수 있습니다.

Without Strict Mode, it was easy to miss that your Effect needed cleanup. By running setup → cleanup → setup instead of setup for your Effect in development, Strict Mode made the missing cleanup logic more noticeable. Strict Mode가 없으면, Effect에 클린업이 필요하다는 사실을 놓치기 쉬웠습니다. Strict Mode는 개발 단계에서 Effect에 대해 셋업만 하는 대신 셋업 → 클린업 → 셋업을 순차로 실행함으로써 누락된 클린업 로직을 더 눈에 띄게 만들었습니다.

Read more about implementing Effect cleanup. Effect에서 클린업을 구현하는 방법에 대해 자세히 알아보세요.


Fixing deprecation warnings enabled by Strict ModeStrict Mode로 지원 중단 경고 수정하기

React warns if some component anywhere inside a <StrictMode> tree uses one of these deprecated APIs: React는 <StrictMode> 트리 내의 컴포넌트가 더 이상 지원되지 않는 API중 하나를 사용하는 경우 경고를 표시합니다:

These APIs are primarily used in older class components so they rarely appear in modern apps. 이러한 API는 주로 오래된 클래스 컴포넌트에서 사용되므로 최신 앱에는 거의 나타나지 않습니다.