createRoot lets you create a root to display React components inside a browser DOM node. createRoot로 브라우저 DOM 노드 안에 React 컴포넌트를 표시하는 루트를 생성할 수 있습니다.

const root = createRoot(domNode, options?)

Reference참조

createRoot(domNode, options?)

Call createRoot to create a React root for displaying content inside a browser DOM element. createRoot를 호출하면 브라우저 DOM 엘리먼트 안에 콘텐츠를 표시할 수 있는 React 루트를 생성합니다.

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

const domNode = document.getElementById('root');
const root = createRoot(domNode);

React will create a root for the domNode, and take over managing the DOM inside it. After you’ve created a root, you need to call root.render to display a React component inside of it: React는 domNode에 대한 루트를 생성하고 그 안에 있는 DOM을 관리합니다. 루트를 생성한 후에는 root.render를 호출해 그 안에 React 컴포넌트를 표시해야 합니다:

root.render(<App />);

An app fully built with React will usually only have one createRoot call for its root component. A page that uses “sprinkles” of React for parts of the page may have as many separate roots as needed. 온전히 React만으로 빌드된 앱에서는 일반적으로 루트 컴포넌트에 대한 createRoot 호출이 하나만 있습니다. 페이지의 일부에 React를 “뿌려서” 사용하는 페이지의 경우에는 루트를 필요한 만큼 많이 작성할 수도 있습니다.

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

Parameters매개변수

  • domNode: A DOM element. React will create a root for this DOM element and allow you to call functions on the root, such as render to display rendered React content. domNode: DOM 엘리먼트. React는 이 DOM 엘리먼트에 대한 루트를 생성하고 렌더링된 React 콘텐츠를 표시하는 render와 같은 함수를 루트에서 호출할 수 있도록 합니다.

  • optional options: An object with options for this React root. 선택적 options: 이 React 루트에 대한 옵션이 있는 객체입니다.

  • Canary only optional onCaughtError: Callback called when React catches an error in an Error Boundary. Called with the error caught by the Error Boundary, and an errorInfo object containing the componentStack. Canary only 선택적 onCaughtError: React가 에러 바운더리에서 에러를 포착할 때 호출되는 콜백. 에러 바운더리에서 포착한 errorcomponentStack을 포함하는 errorInfo 객체와 함께 호출됩니다.

  • Canary only optional onUncaughtError: Callback called when an error is thrown and not caught by an Error Boundary. Called with the error that was thrown, and an errorInfo object containing the componentStack. Canary only 선택적 onUncaughtError: 에러가 발생했지만 에러 바운더리에 잡히지 않은 경우 호출되는 콜백입니다. 발생한 errorcomponentStack을 포함하는 errorInfo 객체와 함께 호출됩니다.

  • optional onRecoverableError: Callback called when React automatically recovers from errors. Called with an error React throws, and an errorInfo object containing the componentStack. Some recoverable errors may include the original error cause as error.cause. 선택적 onRecoverableError: React가 오류로부터 자동으로 복구할 때 호출되는 콜백입니다. React가 던지는 error와, componentStack을 포함하는 errorInfo 객체와 함께 호출됩니다. 복구 가능한 일부 오류에는 원래의 오류 원인이 error.cause로 포함될 수 있습니다.

  • optional identifierPrefix: A string prefix React uses for IDs generated by useId. Useful to avoid conflicts when using multiple roots on the same page. 선택적 identifierPrefix : React가 useId에 의해 생성된 ID에 사용하는 문자열 접두사. 같은 페이지에서 여러개의 루트를 사용할 때 충돌을 피하는 데 유용합니다.

Returns반환값

createRoot returns an object with two methods: render and unmount. createRootrenderunmount 두 가지 메서드가 있는 객체를 반환합니다.

Caveats주의사항

  • If your app is server-rendered, using createRoot() is not supported. Use hydrateRoot() instead. 앱이 서버에서 렌더링되는 경우 createRoot()는 사용할 수 없습니다. 대신 hydrateRoot()를 사용하세요.

  • You’ll likely have only one createRoot call in your app. If you use a framework, it might do this call for you. 앱에 createRoot 호출이 오직 하나만 있을 가능성이 높습니다. 프레임워크를 사용하는 경우 프레임워크가 이 호출을 대신 수행할 수도 있습니다.

  • When you want to render a piece of JSX in a different part of the DOM tree that isn’t a child of your component (for example, a modal or a tooltip), use createPortal instead of createRoot. 컴포넌트의 자식이 아닌 DOM 트리의 다른 부분(예: 모달 또는 툴팁)에 JSX 조각을 렌더링하려는 경우, createRoot 대신 createPortal을 사용하세요.


root.render(reactNode)

Call root.render to display a piece of JSX (“React node”) into the React root’s browser DOM node. root.render를 호출하여 JSX 조각(“React 노드”)을 React 루트의 브라우저 DOM 노드에 표시합니다.

root.render(<App />);

React will display <App /> in the root, and take over managing the DOM inside it. React는 root<App />을 표시하고 그 안에 있는 DOM을 관리합니다.

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

Parameters매개변수

  • reactNode: A React node that you want to display. This will usually be a piece of JSX like <App />, but you can also pass a React element constructed with createElement(), a string, a number, null, or undefined. reactNode: 표시하려는 React 노드. 일반적으로 <App />과 같은 JSX 조각이 되지만, createElement()로 작성한 React 엘리먼트, 문자열, 숫자, null, undefined 등을 전달할 수도 있습니다.

Returns반환값

root.render returns undefined. root.renderundefined를 반환합니다.

Caveats주의사항

  • The first time you call root.render, React will clear all the existing HTML content inside the React root before rendering the React component into it. root.render를 처음 호출하면 React는 React 컴포넌트를 렌더링하기 전에 React 루트 내부의 모든 기존 HTML 콘텐츠를 지웁니다.

  • If your root’s DOM node contains HTML generated by React on the server or during the build, use hydrateRoot() instead, which attaches the event handlers to the existing HTML. 서버에서 또는 빌드 중에 React에 의해 생성된 HTML이 루트의 DOM 노드에 포함된 경우, 대신 이벤트 핸들러를 기존 HTML에 첨부하는 hydrateRoot()를 사용하세요.

  • If you call render on the same root more than once, React will update the DOM as necessary to reflect the latest JSX you passed. React will decide which parts of the DOM can be reused and which need to be recreated by “matching it up” with the previously rendered tree. Calling render on the same root again is similar to calling the set function on the root component: React avoids unnecessary DOM updates. 동일한 루트에서 render를 두 번 이상 호출하면, React는 필요에 따라 DOM을 업데이트하여 사용자가 전달한 최신 JSX를 반영합니다. React는 이전에 렌더링된 트리와 “비교”해서 재사용할 수 있는 부분과 다시 만들어야 하는 부분을 결정합니다. 동일한 루트에서 render를 다시 호출하는 것은 루트 컴포넌트에서 set 함수를 호출하는 것과 비슷합니다. React는 불필요한 DOM 업데이트를 피합니다.


root.unmount()

Call root.unmount to destroy a rendered tree inside a React root. root.unmount를 호출하면 React 루트 내부에서 렌더링된 트리를 삭제합니다.

root.unmount();

An app fully built with React will usually not have any calls to root.unmount. 온전히 React만으로 작성된 앱에는 일반적으로 root.unmount에 대한 호출이 없습니다.

This is mostly useful if your React root’s DOM node (or any of its ancestors) may get removed from the DOM by some other code. For example, imagine a jQuery tab panel that removes inactive tabs from the DOM. If a tab gets removed, everything inside it (including the React roots inside) would get removed from the DOM as well. In that case, you need to tell React to “stop” managing the removed root’s content by calling root.unmount. Otherwise, the components inside the removed root won’t know to clean up and free up global resources like subscriptions. 이 함수는 React 루트의 DOM 노드(또는 그 조상 노드)가 다른 코드에 의해 DOM에서 제거될 수 있는 경우에 주로 유용합니다. 예를 들어, DOM에서 비활성 탭을 제거하는 jQuery 탭 패널을 상상해 보세요. 탭이 제거되면 그 안에 있는 모든 것(내부의 React 루트를 포함)도 DOM에서 제거됩니다. 이 경우 root.unmount를 호출하여 제거된 루트의 콘텐츠 관리를 “중지”하도록 React에 지시해야 합니다. 그렇지 않으면 제거된 루트 내부의 컴포넌트는 구독과 같은 글로벌 리소스를 정리 및 확보하지 않은 채로 머물게 됩니다.

Calling root.unmount will unmount all the components in the root and “detach” React from the root DOM node, including removing any event handlers or state in the tree. root.unmount를 호출하면 루트에 있는 모든 컴포넌트가 unmount되고, 트리상의 이벤트 핸들러나 state가 제거되며, 루트 DOM 노드에서 React가 “분리”됩니다

Parameters매개변수

root.unmount does not accept any parameters. root.unmount는 매개변수를 받지 않습니다.

Returns반환값

root.unmount returns undefined. root.renderundefined를 반환합니다.

Caveats주의사항

  • Calling root.unmount will unmount all the components in the tree and “detach” React from the root DOM node. root.unmount를 호출하면 트리의 모든 컴포넌트가 unmount되고 루트 DOM 노드에서 React가 “분리”됩니다.

  • Once you call root.unmount you cannot call root.render again on the same root. Attempting to call root.render on an unmounted root will throw a “Cannot update an unmounted root” error. However, you can create a new root for the same DOM node after the previous root for that node has been unmounted. root.unmount를 호출한 후에는 같은 루트에서 root.render를 다시 호출할 수 없습니다. unmount된 루트에서 root.render를 호출하려고 하면 “unmount된 root를 업데이트할 수 없습니다.” 오류가 발생합니다. 그러나 해당 노드의 이전 루트가 unmount된 후 동일한 DOM 노드에 새로운 루트를 만들 수는 있습니다.


Usage사용법

Rendering an app fully built with React온전히 React만으로 작성된 앱 렌더링하기

If your app is fully built with React, create a single root for your entire app. 앱이 온전히 React만으로 작성된 경우, 전체 앱에 대해 단일 루트를 생성하세요.

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

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

Usually, you only need to run this code once at startup. It will: 일반적으로 이 코드는 시작할 때 한 번만 실행하면 됩니다.

  1. Find the browser DOM node defined in your HTML. HTML에 정의된 브라우저 DOM 노드를 찾으세요.

  2. Display the React component for your app inside. 그 안에 앱의 React 컴포넌트를 표시하세요.

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

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

If your app is fully built with React, you shouldn’t need to create any more roots, or to call root.render again. 앱이 온전히 React만으로 작성된 경우, 추가적으로 루트를 더 만들거나 root.render를 다시 호출할 필요가 없습니다.

From this point on, React will manage the DOM of your entire app. To add more components, nest them inside the App component. When you need to update the UI, each of your components can do this by using state. When you need to display extra content like a modal or a tooltip outside the DOM node, render it with a portal. 이 시점부터 React는 전체 앱의 DOM을 관리합니다. 컴포넌트를 더 추가하려면 App 컴포넌트 안에 중첩시키세요. UI 업데이트는 각 컴포넌트의 state를 통해 수행할 수 있습니다. 모달이나 툴팁과 같은 추가 콘텐츠를 DOM 노드 외부에 표시해야 하는 경우 포털로 렌더링하세요.

Note

When your HTML is empty, the user sees a blank page until the app’s JavaScript code loads and runs: HTML이 비어있으면, 앱의 JavaScript 코드가 로드되고 실행될 때까지 사용자에게 빈 페이지가 표시됩니다:

<div id="root"></div>

This can feel very slow! To solve this, you can generate the initial HTML from your components on the server or during the build. Then your visitors can read text, see images, and click links before any of the JavaScript code loads. We recommend using a framework that does this optimization out of the box. Depending on when it runs, this is called server-side rendering (SSR) or static site generation (SSG). 이것은 매우 느리게 느껴질 수 있습니다! 이 문제를 해결하기 위해 서버에서 또는 빌드 중에 컴포넌트로부터 초기 HTML을 생성할 수 있습니다. 그러면 방문자는 JavaScript 코드가 로드되기 전에 텍스트를 읽고, 이미지를 보고, 링크를 클릭할 수 있습니다. 이 최적화를 기본적으로 수행하는 프레임워크를 사용하는 것이 좋습니다. 실행 시점에 따라 이를 서버측 렌더링(SSR) 또는 정적 사이트 생성(SSG) 이라고 합니다.

Pitfall | 함정

Apps using server rendering or static generation must call hydrateRoot instead of createRoot. React will then hydrate (reuse) the DOM nodes from your HTML instead of destroying and re-creating them. 서버 렌더링이나 정적 생성을 사용하는 앱은 createRoot 대신 hydrateRoot를 호출해야 합니다. 그러면 React는 DOM 노드를 파괴하고 다시 생성하는 대신 HTML으로부터 hydrate(재사용)합니다.


Rendering a page partially built with ReactReact로 부분적으로 빌드된 페이지 렌더링하기

If your page isn’t fully built with React, you can call createRoot multiple times to create a root for each top-level piece of UI managed by React. You can display different content in each root by calling root.render. 페이지가 React만으로 작성되지 않은 경우, React가 관리하는 각 최상위 UI에 대한 루트를 생성하기 위해 createRoot를 여러 번 호출할 수 있습니다. 루트마다 root.render를 호출함으로써 각각 다른 콘텐츠를 표시할 수 있습니다.

Here, two different React components are rendered into two DOM nodes defined in the index.html file: 다음 예시에서는 서로 다른 두 개의 React 컴포넌트가 index.html 파일에 정의된 두 개의 DOM 노드에 렌더링됩니다:

import './styles.css';
import { createRoot } from 'react-dom/client';
import { Comments, Navigation } from './Components.js';

const navDomNode = document.getElementById('navigation');
const navRoot = createRoot(navDomNode); 
navRoot.render(<Navigation />);

const commentDomNode = document.getElementById('comments');
const commentRoot = createRoot(commentDomNode); 
commentRoot.render(<Comments />);

You could also create a new DOM node with document.createElement() and add it to the document manually. document.createElement()를 사용하여 새 DOM 노드를 생성하고 문서에 수동으로 추가할 수도 있습니다.

const domNode = document.createElement('div');
const root = createRoot(domNode);
root.render(<Comment />);
document.body.appendChild(domNode); // You can add it anywhere in the document

To remove the React tree from the DOM node and clean up all the resources used by it, call root.unmount. DOM 노드에서 React 트리를 제거하고 이 트리가 사용하는 모든 리소스를 정리하려면 root.unmount를 호출하세요.

root.unmount();

This is mostly useful if your React components are inside an app written in a different framework. 이 기능은 React 컴포넌트가 다른 프레임워크로 작성된 앱 내부에 있는 경우에 주로 유용합니다.


Updating a root component루트 컴포넌트 업데이트하기

You can call render more than once on the same root. As long as the component tree structure matches up with what was previously rendered, React will preserve the state. Notice how you can type in the input, which means that the updates from repeated render calls every second in this example are not destructive: 같은 루트에서 render를 두 번 이상 호출할 수도 있습니다. 컴포넌트 트리 구조가 이전 렌더링과 일치하는 한, React는 기존 state를 유지합니다. 다음 예제에서 input에 어떻게 타이핑하든 관계 없이, 매 초 반복되는 render 호출로 인한 업데이트가 아무런 문제를 일으키지 않음을 주목하세요:

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

const root = createRoot(document.getElementById('root'));

let i = 0;
setInterval(() => {
  root.render(<App counter={i} />);
  i++;
}, 1000);

It is uncommon to call render multiple times. Usually, your components will update state instead. render를 여러번 호출하는 경우는 흔하지 않습니다. 대신 일반적으로 컴포넌트가 state를 업데이트합니다.

Show a dialog for uncaught errors

Canary

onUncaughtError is only available in the latest React Canary release.

By default, React will log all uncaught errors to the console. To implement your own error reporting, you can provide the optional onUncaughtError root option:

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

const root = createRoot(
document.getElementById('root'),
{
onUncaughtError: (error, errorInfo) => {
console.error(
'Uncaught error',
error,
errorInfo.componentStack
);
}
}
);
root.render(<App />);

The onUncaughtError option is a function called with two arguments:

  1. The error that was thrown.
  2. An errorInfo object that contains the componentStack of the error.

You can use the onUncaughtError root option to display error dialogs:

import { createRoot } from "react-dom/client";
import App from "./App.js";
import {reportUncaughtError} from "./reportError";
import "./styles.css";

const container = document.getElementById("root");
const root = createRoot(container, {
  onUncaughtError: (error, errorInfo) => {
    if (error.message !== 'Known error') {
      reportUncaughtError({
        error,
        componentStack: errorInfo.componentStack
      });
    }
  }
});
root.render(<App />);

Displaying Error Boundary errors

Canary

onCaughtError is only available in the latest React Canary release.

By default, React will log all errors caught by an Error Boundary to console.error. To override this behavior, you can provide the optional onCaughtError root option to handle errors caught by an Error Boundary:

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

const root = createRoot(
document.getElementById('root'),
{
onCaughtError: (error, errorInfo) => {
console.error(
'Caught error',
error,
errorInfo.componentStack
);
}
}
);
root.render(<App />);

The onCaughtError option is a function called with two arguments:

  1. The error that was caught by the boundary.
  2. An errorInfo object that contains the componentStack of the error.

You can use the onCaughtError root option to display error dialogs or filter known errors from logging:

import { createRoot } from "react-dom/client";
import App from "./App.js";
import {reportCaughtError} from "./reportError";
import "./styles.css";

const container = document.getElementById("root");
const root = createRoot(container, {
  onCaughtError: (error, errorInfo) => {
    if (error.message !== 'Known error') {
      reportCaughtError({
        error, 
        componentStack: errorInfo.componentStack,
      });
    }
  }
});
root.render(<App />);

Displaying a dialog for recoverable errors

React may automatically render a component a second time to attempt to recover from an error thrown in render. If successful, React will log a recoverable error to the console to notify the developer. To override this behavior, you can provide the optional onRecoverableError root option:

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

const root = createRoot(
document.getElementById('root'),
{
onRecoverableError: (error, errorInfo) => {
console.error(
'Recoverable error',
error,
error.cause,
errorInfo.componentStack,
);
}
}
);
root.render(<App />);

The onRecoverableError option is a function called with two arguments:

  1. The error that React throws. Some errors may include the original cause as error.cause.
  2. An errorInfo object that contains the componentStack of the error.

You can use the onRecoverableError root option to display error dialogs:

import { createRoot } from "react-dom/client";
import App from "./App.js";
import {reportRecoverableError} from "./reportError";
import "./styles.css";

const container = document.getElementById("root");
const root = createRoot(container, {
  onRecoverableError: (error, errorInfo) => {
    reportRecoverableError({
      error,
      cause: error.cause,
      componentStack: errorInfo.componentStack,
    });
  }
});
root.render(<App />);


Troubleshooting문제 해결

I’ve created a root, but nothing is displayed루트를 생성했는데 아무것도 표시되지 않습니다

Make sure you haven’t forgotten to actually render your app into the root: 실제로 앱을 루트에 렌더링하는 것을 잊지 않았는지 확인하세요:

import { createRoot } from 'react-dom/client';
import App from './App.js';

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

Until you do that, nothing is displayed. root.render(...) 명령 없이는 아무것도 표시되지 않습니다.


I’m getting an error: “You passed a second argument to root.render”

A common mistake is to pass the options for createRoot to root.render(...):

Console
Warning: You passed a second argument to root.render(…) but it only accepts one argument.

To fix, pass the root options to createRoot(...), not root.render(...):

// 🚩 Wrong: root.render only takes one argument.
root.render(App, {onUncaughtError});

// ✅ Correct: pass options to createRoot.
const root = createRoot(container, {onUncaughtError});
root.render(<App />);

I’m getting an error: “Target container is not a DOM element""대상 컨테이너가 DOM 엘리먼트가 아닙니다” 라는 오류가 발생합니다

This error means that whatever you’re passing to createRoot is not a DOM node. 이 오류는 createRoot에 전달한 것이 DOM 노드가 아님을 의미합니다.

If you’re not sure what’s happening, try logging it: 무슨 일이 발생했는지 확실하지 않다면 로깅을 시도해 보세요:

const domNode = document.getElementById('root');
console.log(domNode); // ???
const root = createRoot(domNode);
root.render(<App />);

For example, if domNode is null, it means that getElementById returned null. This will happen if there is no node in the document with the given ID at the time of your call. There may be a few reasons for it: 예를 들어, domNodenull이면 getElementByIdnull을 반환했음을 의미합니다. 이는 호출 시점에 문서에 지정된 ID를 가진 노드가 없는 경우에 발생합니다. 몇 가지 이유가 있을 수 있습니다.

  1. The ID you’re looking for might differ from the ID you used in the HTML file. Check for typos! 찾고자 하는 ID가 HTML 파일에서 사용한 ID와 다를 수 있습니다. 오타가 있는지 확인하세요!

  2. Your bundle’s <script> tag cannot “see” any DOM nodes that appear after it in the HTML. 번들의 <script> 태그는 HTML에서 그보다 뒤에 있는 DOM 노드를 “인식할” 수 없습니다.

Another common way to get this error is to write createRoot(<App />) instead of createRoot(domNode). 또다른 일반적인 사례는 createRoot(domNode) 대신 createRoot(<App />)으로 작성했을 경우입니다.


I’m getting an error: “Functions are not valid as a React child.""함수가 React 자식으로 유효하지 않습니다” 오류가 발생합니다.

This error means that whatever you’re passing to root.render is not a React component. 이 오류는 root.render에 전달하는 것이 React 컴포넌트가 아님을 의미합니다.

This may happen if you call root.render with Component instead of <Component />: 이 오류는 <Component /> 대신 Componentroot.render를 호출할 때 발생할 수 있습니다:

// 🚩 Wrong: App is a function, not a Component.
root.render(App);

// ✅ Correct: <App /> is a component.
root.render(<App />);

Or if you pass a function to root.render, instead of the result of calling it: 또는 함수를 호출한 결과 대신 root.render에 함수 자체를 전달했을 때도 발생할 수 있습니다:

// 🚩 Wrong: createApp is a function, not a component.
root.render(createApp);

// ✅ Correct: call createApp to return a component.
root.render(createApp());

My server-rendered HTML gets re-created from scratch서버에서 렌더링된 HTML이 처음부터 다시 생성됩니다

If your app is server-rendered and includes the initial HTML generated by React, you might notice that creating a root and calling root.render deletes all that HTML, and then re-creates all the DOM nodes from scratch. This can be slower, resets focus and scroll positions, and may lose other user input. 앱이 서버에서 렌더링되고 React의 초기 HTML을 포함하는 경우에, 루트를 생성해서 root.render를 호출하면, 모든 HTML이 삭제되고 모든 DOM 노드가 처음부터 다시 생성되는 것을 볼 수 있습니다. 이렇게 하면 속도가 느려지고, 포커스와 스크롤 위치가 재설정되며, 그 밖의 다른 사용자 입력들이 손실될 수 있습니다.

Server-rendered apps must use hydrateRoot instead of createRoot: 서버에서 렌더링된 앱은 createRoot 대신 hydrateRoot를 사용해야 합니다:

import { hydrateRoot } from 'react-dom/client';
import App from './App.js';

hydrateRoot(
document.getElementById('root'),
<App />
);

Note that its API is different. In particular, usually there will be no further root.render call. API가 다르다는 점에 유의하세요. 특히, 일반적으로 root.render를 아예 호출하지 않습니다.