createRoot
createRoot
는 브라우저 DOM 노드 안에 React 컴포넌트를 표시할 수 있는 루트를 생성합니다.
const root = createRoot(domNode, options?)
- 레퍼런스
- createRoot(domNode, options?)
- root.render(reactNode)
- root.unmount()
- 사용법
- 전체가 React로 구성된 앱 렌더링하기
- 일부만 React로 구성된 페이지 렌더링하기
- 루트 컴포넌트 업데이트하기
- 프로덕션 환경에서 에러 로깅하기
- 문제 해결
- 루트를 만들었는데 아무것도 표시되지 않음
- root.render에 두 번째 인자를 전달했을 때의 에러
- "Target container is not a DOM element" 에러
- "Functions are not valid as a React child." 에러
- 서버 렌더링된 HTML이 새로 생성되는 문제
레퍼런스
createRoot(domNode, options?)
브라우저 DOM 요소에 React 루트를 생성하려면 createRoot
를 호출하세요.
import { createRoot } from 'react-dom/client';
const domNode = document.getElementById('root');
const root = createRoot(domNode);
React는 해당 domNode
에 루트를 만들고, 그 내부의 DOM을 관리합니다. 루트를 만든 후에는 반드시 root.render
를 호출해 React 컴포넌트를 표시해야 합니다.
root.render(<App />);
파라미터
domNode
: DOM 요소. React가 이 요소에 루트를 만들고, 관련 메서드(render
,unmount
)를 사용할 수 있게 합니다.options
(선택): 객체. 루트에 대한 옵션입니다.onCaughtError
: Error Boundary에서 에러를 잡았을 때 호출되는 콜백.onUncaughtError
: Error Boundary에서 잡히지 않은 에러가 발생했을 때 호출되는 콜백.onRecoverableError
: React가 자동으로 복구 가능한 에러를 처리할 때 호출되는 콜백.identifierPrefix
: 여러 루트에서 useId로 생성되는 ID의 접두사.
반환값
createRoot
는 render
와 unmount
메서드를 가진 객체를 반환합니다.
주의사항
- 서버 렌더링된 앱에서는
createRoot()
대신hydrateRoot()
를 사용해야 합니다. - 대부분의 앱에서는
createRoot
호출이 한 번만 필요합니다. 프레임워크를 사용한다면 프레임워크가 대신 호출할 수 있습니다. - JSX를 DOM 트리의 다른 위치에 렌더링하려면
createRoot
대신createPortal
을 사용하세요.
root.render(reactNode)
root.render
를 호출해 React 노드(JSX)를 해당 루트의 DOM 노드에 표시합니다.
root.render(<App />);
파라미터
reactNode
: 표시할 React 노드(JSX, React 엘리먼트, 문자열, 숫자, null, undefined 등).
반환값
root.render
는 아무것도 반환하지 않습니다.
주의사항
- 첫
root.render
호출 시, 해당 DOM 노드의 기존 HTML은 모두 지워지고 React 컴포넌트가 렌더링됩니다. - 서버 렌더링된 HTML이 있다면
createRoot
대신hydrateRoot
를 사용하세요. - 같은 루트에서 여러 번
render
를 호출하면 React가 DOM을 효율적으로 업데이트합니다. - 렌더링은 동기적으로 시작되지만,
root.render(...)
이후의 코드는 해당 렌더의 effect(useLayoutEffect
,useEffect
)가 실행되기 전에 실행될 수 있습니다. effect 타이밍이 중요하다면flushSync
로 감싸세요.
root.unmount()
root.unmount
를 호출하면 해당 루트의 React 트리를 DOM에서 제거하고, 관련 리소스를 정리합니다.
root.unmount();
대부분의 앱에서는 직접 호출할 일이 드뭅니다. 외부 코드가 DOM 노드를 제거할 때 필요할 수 있습니다.
사용법
전체가 React로 구성된 앱 렌더링하기
import { createRoot } from 'react-dom/client';
import App from './App.js';
const root = createRoot(document.getElementById('root'));
root.render(<App />);
일부만 React로 구성된 페이지 렌더링하기
import { createRoot } from 'react-dom/client';
import { Comments, Navigation } from './Components.js';
const navRoot = createRoot(document.getElementById('navigation'));
navRoot.render(<Navigation />);
const commentRoot = createRoot(document.getElementById('comments'));
commentRoot.render(<Comments />);
루트 컴포넌트 업데이트하기
같은 루트에서 여러 번 render
를 호출하면 React가 상태를 보존하며 DOM을 업데이트합니다.
import { createRoot } from 'react-dom/client';
import App from './App.js';
const root = createRoot(document.getElementById('root'));
let i = 0;
setInterval(() => {
root.render(<App counter={i} />);
i++;
}, 1000);
프로덕션 환경에서 에러 로깅하기
옵션으로 에러 핸들러를 지정해 에러 로깅 시스템을 구현할 수 있습니다.
import { createRoot } from "react-dom/client";
import { reportCaughtError } from "./reportError";
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 />);
문제 해결
루트를 만들었는데 아무것도 표시되지 않음
createRoot
만 호출하고 root.render
를 호출하지 않으면 아무것도 표시되지 않습니다.
import { createRoot } from 'react-dom/client';
import App from './App.js';
const root = createRoot(document.getElementById('root'));
root.render(<App />);
root.render에 두 번째 인자를 전달했을 때의 에러
root.render
는 한 개의 인자만 받습니다. 옵션은 createRoot
에 전달해야 합니다.
// 🚩 잘못된 예시
root.render(App, {onUncaughtError});
// ✅ 올바른 예시
const root = createRoot(container, {onUncaughtError});
root.render(<App />);
"Target container is not a DOM element" 에러
createRoot
에 전달한 값이 DOM 노드가 아닐 때 발생합니다. 예를 들어, getElementById
가 null
을 반환하면 이 에러가 발생합니다.
const domNode = document.getElementById('root');
console.log(domNode); // ???
const root = createRoot(domNode);
root.render(<App />);
"Functions are not valid as a React child." 에러
root.render
에 함수 자체를 전달하면 발생합니다. JSX 또는 React 엘리먼트를 전달해야 합니다.
// 🚩 잘못된 예시
root.render(App);
// ✅ 올바른 예시
root.render(<App />);
서버 렌더링된 HTML이 새로 생성되는 문제
서버 렌더링된 HTML이 있다면 createRoot
대신 hydrateRoot
를 사용해야 합니다.
import { hydrateRoot } from 'react-dom/client';
import App from './App.js';
hydrateRoot(
document.getElementById('root'),
<App />
);