createRoot
createRoot позволяет создать корень для отображения компонентов React внутри узла DOM браузера.
const root = createRoot(domNode, options?)
Справочник
createRoot(domNode, options?)
Вызовите createRoot для создания корня React для отображения содержимого внутри элемента DOM браузера.
import { createRoot } from 'react-dom/client';
const domNode = document.getElementById('root');
const root = createRoot(domNode); React создаст корень для domNode, и возьмёт на себя управление DOM внутри него. После создания корня, вам нужно вызвать root.render, чтобы отобразить компонент React внутри него:
root.render(<App />); Приложение, полностью построенное с React, обычно содержит только один вызов createRoot для своего корневого компонента. Страница, использующая «дополнения» React для части страницы, может иметь столько отдельных корней, сколько необходимо.
См. дополнительные примеры ниже.
Параметры
-
domNode: Элемент DOM. React создаст корень для этого элемента DOM и позволит вам вызывать функции на корне, такие какrenderдля отображения отрендеренного содержимого React. -
необязательный
options: Объект с параметрами для этого корня React.-
необязательный
onCaughtError: Обратный вызов, вызываемый, когда React перехватывает ошибку в Error Boundary. Вызывается с перехваченнойerrorошибкой Error Boundary и объектомerrorInfo, содержащимcomponentStack. -
необязательный
onUncaughtError: Обратный вызов, вызываемый, когда ошибка выбрасывается и не перехватывается Error Boundary. Вызывается сerrorошибкой, которая была выброшена, и объектомerrorInfo, содержащимcomponentStack. -
необязательный
onRecoverableError: Обратный вызов, вызываемый, когда React автоматически восстанавливается от ошибок. Вызывается с выброшеннойerrorошибкой React и объектомerrorInfo, содержащимcomponentStack. Некоторые восстанавливаемые ошибки могут содержать первопричину ошибки в качествеerror.cause. -
необязательный
identifierPrefix: Префикс строки, который React использует для идентификаторов, генерируемых с помощьюuseId. Полезно для предотвращения конфликтов при использовании нескольких корней на одной странице.
-
необязательный
Возвращаемое значение
createRoot возвращает объект с двумя методами: render и unmount.
Примечания
- Если ваше приложение серверно-отрендеренное, использование
createRoot()не поддерживается. ИспользуйтеhydrateRoot()вместо этого. - Вероятно, в вашем приложении будет только один вызов
createRoot. Если вы используете фреймворк, он может выполнить этот вызов за вас. - Когда вам нужно отобразить JSX в другой части дерева DOM, которое не является дочерним элементом вашего компонента (например, модальное окно или всплывающую подсказку), используйте
createPortalвместоcreateRoot.
root.render(reactNode)
Вызовите root.render для отображения фрагмента JSX («узла React») в узел DOM браузера корневого компонента React.
root.render(<App />); React отобразит <App /> в root, и возьмёт на себя управление DOM внутри него.
См. дополнительные примеры ниже.
Параметры
-
reactNode: Узел React, который вы хотите отобразить. Обычно это фрагмент JSX, как<App />, но вы также можете передать элемент React, созданный с помощьюcreateElement(), строку, число,null, илиundefined.
Возвращаемое значение
root.render возвращает undefined.
Примечания
-
В первый раз при вызове
root.render, React очистит всё существующее содержимое HTML внутри корня React перед рендерингом компонента React в него. -
Если узел DOM вашего корня содержит HTML, сгенерированный React на сервере или во время сборки, используйте
hydrateRoot()вместо этого, который прикрепляет обработчики событий к существующему HTML. -
Если вы вызываете
renderна том же корне более одного раза, React обновит DOM по мере необходимости, чтобы отразить последний переданный JSX. React решит, какие части DOM можно повторно использовать, а какие необходимо пересоздать, «сопоставив» его с ранее отрендеренным деревом. Вызовrenderна том же корне аналогичен вызову функцииsetкомпонента корня: React избегает ненужных обновлений DOM.
root.unmount()
Вызовите root.unmount для уничтожения отрендеренного дерева внутри корня React.
root.unmount(); В полностью построенном приложении React обычно нет вызовов root.unmount.
Это полезно в основном в том случае, если узел DOM вашего корня React (или любой из его предков) может быть удалён из DOM другим кодом. Например, представьте jQuery панель вкладок, которая удаляет неактивные вкладки из DOM. Если вкладка удаляется, всё внутри неё (включая корни React внутри) также будет удалено из DOM. В этом случае вам нужно сказать React «остановить» управление содержимым удалённого корня, вызвав root.unmount. В противном случае компоненты внутри удалённого корня не будут знать, как очистить и освободить глобальные ресурсы, такие как подписки.
Вызов root.unmount размонтирует все компоненты в корне и «отсоединит» React от корневого узла DOM, включая удаление любых обработчиков событий или состояния в дереве.
Параметры
root.unmount не принимает никаких параметров.
Возвращаемое значение
root.unmount возвращает undefined.
Примечания
-
Вызов
root.unmountразмонтирует все компоненты в дереве и «отсоединит» React от корневого узла DOM. -
После вызова
root.unmountвы не можете снова вызватьroot.renderна том же корне. Попытка вызватьroot.renderна размонтированном корне приведёт к ошибке «Нельзя обновить размонтированный корень». Однако вы можете создать новый корень для того же узла DOM после того, как предыдущий корень для этого узла был размонтирован.
Использование
Отображение полностью построенного приложения с React
Если ваше приложение полностью построено с React, создайте один корень для всего приложения.
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(<App />); Обычно этот код нужно выполнить один раз при запуске. Он:
- Найдёт узел DOM браузера, определённый в вашем HTML.
- Отобразит компонент React вашего приложения внутри него.
import { createRoot } from 'react-dom/client'; import App from './App.js'; import './styles.css'; const root = createRoot(document.getElementById('root')); root.render(<App />);
Если ваше приложение полностью построено с React, вам не нужно создавать дополнительные корни или вызывать root.render снова.
С этого момента React будет управлять DOM вашего приложения. Чтобы добавить больше компонентов, вложите их внутри компонента App. При необходимости обновления пользовательского интерфейса каждый из ваших компонентов может сделать это с помощью состояния. При необходимости отображения дополнительного содержимого, такого как модальное окно или всплывающая подсказка, вне узла DOM, отобразите его с помощью портала.
Примечание
Если ваш HTML пустой, пользователь видит пустую страницу до тех пор, пока не загрузится и выполнится JavaScript-код приложения:
<div id="root"></div>
Это может казаться очень медленным! Чтобы решить эту проблему, вы можете генерировать начальный HTML из своих компонентов на сервере или во время сборки. Тогда посетители смогут читать текст, видеть изображения и нажимать ссылки до загрузки любого JavaScript-кода. Мы рекомендуем использовать фреймворк, который выполняет эту оптимизацию «из коробки». В зависимости от времени выполнения это называется рендерингом на стороне сервера (SSR) или генерацией статических сайтов (SSG).
Опасность
Приложения, использующие серверный рендеринг или статическую генерацию, должны вызывать hydrateRoot вместо createRoot. React затем гидратирует (переиспользует) узлы DOM из вашего HTML вместо уничтожения и пересоздания их.
Отображение страницы, частично построенной с React
Если ваша страница не полностью построена с React, вы можете вызвать createRoot несколько раз, чтобы создать корень для каждого верхнего уровня пользовательского интерфейса, управляемого React. Вы можете отобразить разное содержимое в каждом корне, вызвав root.render.
Здесь два разных компонента React отрендерены в два узла DOM, определённые в файле index.html:
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 />);
Вы также можете создать новый узел DOM с помощью document.createElement() и добавить его в документ вручную.
const domNode = document.createElement('div');
const root = createRoot(domNode);
root.render(<Comment />);
document.body.appendChild(domNode); // You can add it anywhere in the document Чтобы удалить дерево React из узла DOM и очистить все используемые им ресурсы, вызовите root.unmount.
root.unmount(); Это полезно в основном в том случае, если ваши компоненты React находятся внутри приложения, написанного на другом фреймворке.
Обновление компонента корня
Вы можете вызвать render более одного раза на том же корне. Пока структура дерева компонентов соответствует тому, что было отображено ранее, React сохранит состояние.
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);
Не рекомендуется вызывать render несколько раз. Обычно ваши компоненты будут обновлять состояние вместо этого.
Отображение диалогового окна для непредвиденных ошибок
По умолчанию React будет регистрировать все непредвиденные ошибки в консоли. Для реализации собственной системы отслеживания ошибок вы можете указать необязательный параметр onUncaughtError корневого элемента:
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 />); Параметр onUncaughtError — это функция, которая вызывается с двумя аргументами:
- Ошибка error, которая была сгенерирована.
- Объект errorInfo, содержащий componentStack ошибки.
Вы можете использовать параметр onUncaughtError корневого элемента для отображения диалоговых окон об ошибках:
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 />);
Отображение ошибок границ ошибок
По умолчанию React будет регистрировать все ошибки, перехваченные границей ошибок, в console.error. Чтобы переопределить это поведение, вы можете указать необязательный параметр onCaughtError корневого элемента для обработки ошибок, перехваченных границей ошибок:
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 />); Параметр onCaughtError — это функция, которая вызывается с двумя аргументами:
- Ошибка error, перехваченная границей.
- Объект errorInfo, содержащий componentStack ошибки.
Вы можете использовать параметр onCaughtError корневого элемента для отображения диалоговых окон об ошибках или фильтрации известных ошибок из логов:
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 />);
Отображение диалогового окна для исправимых ошибок
React может автоматически повторно отобразить компонент, чтобы попытаться восстановить ошибку, выброшенную в render. Если это успешно, React запишет исправимую ошибку в консоль, чтобы уведомить разработчика. Чтобы переопределить это поведение, вы можете указать необязательный параметр onRecoverableError корневого элемента:
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 />); Параметр onRecoverableError — это функция, которая вызывается с двумя аргументами:
- Ошибка error, которую бросает React. Некоторые ошибки могут содержать исходную причину в виде error.cause.
- Объект errorInfo, содержащий componentStack ошибки.
Вы можете использовать параметр onRecoverableError корневого элемента для отображения диалоговых окон об ошибках:
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 />);
Отладка
Я создал корень, но ничего не отображается
Убедитесь, что вы не забыли отобразить ваше приложение в корневой элемент:
import { createRoot } from 'react-dom/client';
import App from './App.js';
const root = createRoot(document.getElementById('root'));
root.render(<App />); Пока вы этого не сделаете, ничего не отобразится.
Я получаю ошибку: «Вы передали второй аргумент в root.render»
Распространённая ошибка — передача параметров для createRoot в root.render(...):
Для исправления передайте параметры корня в createRoot(...), а не в 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 />); Я получаю ошибку: «Целевой контейнер не является элементом DOM»
Эта ошибка означает, что то, что вы передаёте в createRoot, не является узлом DOM.
Если вы не уверены, что происходит, попробуйте вывести это в лог:
const domNode = document.getElementById('root');
console.log(domNode); // ???
const root = createRoot(domNode);
root.render(<App />); Например, если domNode равно null, это означает, что getElementById вернул null. Это произойдёт, если в документе в момент вызова нет узла с заданным идентификатором. Причин этому может быть несколько:
- Идентификатор, который вы ищете, может отличаться от идентификатора, используемого в файле HTML. Проверьте на наличие опечаток!
- Тег
<script>вашего бандла не может «увидеть» узлы DOM, которые появляются после него в HTML.
Ещё один распространённый способ получения этой ошибки — написать createRoot(<App />) вместо createRoot(domNode).
Я получаю ошибку: «Функции не являются допустимыми как React-дочерние элементы»
Эта ошибка означает, что то, что вы передаёте в root.render, не является React-компонентом.
Это может произойти, если вы вызываете root.render с Component вместо <Component />:
// 🚩 Wrong: App is a function, not a Component.
root.render(App);
// ✅ Correct: <App /> is a component.
root.render(<App />); Или если вы передаёте функцию в root.render, вместо результата её вызова:
// 🚩 Wrong: createApp is a function, not a component.
root.render(createApp);
// ✅ Correct: call createApp to return a component.
root.render(createApp()); Мой HTML, отрендеренный на сервере, создаётся заново
Если ваше приложение рендерится на сервере и содержит начальный HTML, сгенерированный React, вы можете заметить, что создание корня и вызов root.render удаляет весь этот HTML и затем заново создаёт все узлы DOM. Это может быть медленнее, сбрасывает фокус и положение прокрутки и может потерять другие пользовательские данные.
Приложения, отрендеренные на сервере, должны использовать hydrateRoot вместо createRoot:
import { hydrateRoot } from 'react-dom/client';
import App from './App.js';
hydrateRoot(
document.getElementById('root'),
<App />
); Обратите внимание, что его API отличается. В частности, обычно не будет последующего вызова root.render.
© 2013–present Facebook Inc.
Licensed under the Creative Commons Attribution 4.0 International Public License.
https://react.dev/reference/react-dom/client/createRoot