createRoot¶
createRoot
позволяет создать корень для отображения компонентов React внутри узла DOM браузера.
1 |
|
Описание¶
createRoot(domNode, options?)
¶
Вызовите createRoot
для создания корня React для отображения содержимого внутри элемента DOM браузера.
1 2 3 4 |
|
React создаст корень для domNode
и возьмет на себя управление DOM внутри него. После создания корня необходимо вызвать root.render
, чтобы отобразить внутри него компонент React:
1 |
|
Приложение, полностью построенное на React, обычно имеет только один вызов createRoot
для своего корневого компонента. Страница, которая использует "брызги" React для частей страницы, может иметь столько отдельных корней, сколько необходимо.
Параметры
domNode
: DOM-элемент. React создаст корень для этого DOM-элемента и позволит вам вызывать функции на корне, такие какrender
для отображения отрисованного содержимого React.- опционально
options
: Объект с опциями для этого корня React.- optional
onRecoverableError
: Обратный вызов, вызываемый, когда React автоматически восстанавливает ошибки. - optional
identifierPrefix
: Строковый префикс, который React использует для идентификаторов, генерируемыхuseId
. Полезно для предотвращения конфликтов при использовании нескольких корней на одной странице.
- optional
Возвращает
createRoot
возвращает объект с двумя методами: render
и unmount
.
Ограничения
- Если ваше приложение рендерится на сервере, использование
createRoot()
не поддерживается. Вместо этого используйтеhydrateRoot()
. - Скорее всего, в вашем приложении будет только один вызов
createRoot
. Если вы используете фреймворк, он может выполнить этот вызов за вас. - Когда вы хотите отобразить JSX в другой части дерева DOM, которая не является дочерней для вашего компонента (например, модальный экран или всплывающая подсказка), используйте
createPortal
вместоcreateRoot
.
root.render(reactNode)
¶
Вызовите root.render
для отображения части JSX ("React node") в DOM-узел браузера React root.
1 |
|
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.
1 |
|
Приложение, полностью построенное на React, обычно не содержит вызовов root.unmount
.
Это в основном полезно, если DOM-узел вашего React root (или любой из его предков) может быть удален из DOM каким-либо другим кодом. Например, представьте себе панель вкладок jQuery, которая удаляет неактивные вкладки из DOM. Если вкладка будет удалена, все внутри нее (включая React roots внутри) также будет удалено из DOM. В этом случае вам нужно сказать React "прекратить" управление содержимым удаленного корня, вызвав root.unmount
. В противном случае компоненты внутри удаленного корня не будут знать, что нужно очистить и освободить глобальные ресурсы, такие как подписки.
Вызов root.unmount
размонтирует все компоненты в корне и "отсоединит" React от корневого DOM-узла, включая удаление любых обработчиков событий или состояния в дереве.
Параметры
root.unmount
не принимает никаких параметров.
Возвраты
root.unmount
возвращает не определено
.
Ограничения
- Вызов
root.unmount
приведет к размонтированию всех компонентов в дереве и "отсоединению" React от корневого DOM-узла. - После вызова
root.unmount
вы не сможете снова вызватьroot.render
на том же корне. Попытка вызватьroot.render
на немонтированном корне приведет к ошибке "Cannot update an unmounted root". Однако вы можете создать новый корень для одного и того же узла DOM после того, как предыдущий корень для этого узла был размонтирован.
Использование¶
Рендеринг приложения, полностью построенного на React¶
Если ваше приложение полностью построено с помощью React, создайте единый корень для всего приложения.
1 2 3 4 |
|
Обычно этот код нужно запускать только один раз при запуске. Он выполнит:
- Найдет узел DOM браузера, определенный в вашем HTML.
- Отобразит компонент React для вашего приложения внутри.
1 2 3 4 5 6 7 8 9 10 |
|
1 2 3 4 5 6 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Если ваше приложение полностью построено на React, вам не нужно больше создавать корни или снова вызывать root.render
С этого момента React будет управлять DOM всего вашего приложения. Чтобы добавить больше компонентов, вложите их внутрь компонента App
Когда вам нужно обновить пользовательский интерфейс, каждый из ваших компонентов может сделать это, используя состояние Когда вам нужно отобразить дополнительный контент, например, модальное окно или подсказку, вне узла DOM, отобразите его с помощью портала.
Когда ваш HTML пуст, пользователь видит пустую страницу, пока не загрузится и не запустится код JavaScript приложения:
1 |
|
Это может показаться очень медленным! Чтобы решить эту проблему, вы можете генерировать исходный HTML из ваших компонентов на сервере или во время сборки. Тогда ваши посетители смогут читать текст, видеть изображения и нажимать на ссылки до того, как загрузится код JavaScript. Мы рекомендуем использовать фреймворк, который выполняет эту оптимизацию из коробки. В зависимости от того, когда она выполняется, это называется рендеринг на стороне сервера (SSR) или статическая генерация сайта (SSG).
Серверный рендеринг
Приложения, использующие серверный рендеринг или статическую генерацию, должны вызывать hydrateRoot
вместо createRoot
. React будет гидрировать (повторно использовать) узлы DOM из вашего HTML вместо их уничтожения и повторного создания.
Рендеринг страницы, частично построенной на React¶
Если ваша страница не полностью построена на React, вы можете вызвать createRoot
несколько раз, чтобы создать корень для каждой части пользовательского интерфейса верхнего уровня, управляемой React. Вы можете отображать различное содержимое в каждом корне, вызывая root.render
.
Здесь два разных компонента React отображаются в двух узлах DOM, определенных в файле index.html
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
Вы также можете создать новый узел DOM с помощью document.createElement()
и добавить его в документ вручную.
1 2 3 4 5 |
|
Чтобы удалить дерево React из узла DOM и очистить все используемые им ресурсы, вызовите root.unmount
.
1 |
|
Это особенно полезно, если ваши компоненты React находятся внутри приложения, написанного на другом фреймворке.
Обновление корневого компонента¶
Вы можете вызывать render
более одного раза для одного и того же корня. Пока структура дерева компонентов соответствует тому, что было отображено ранее, React будет сохранять состояние. Обратите внимание, что вы можете вводить данные, что означает, что обновления от повторных вызовов render
каждую секунду в этом примере не являются разрушительными:
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 5 6 7 8 |
|
Очень редко приходится вызывать render
несколько раз. Обычно вместо этого ваши компоненты будут обновлять состояние.
Устранение неполадок¶
Я создал корень, но ничего не отображается¶
Убедитесь, что вы не забыли на самом деле создать ваше приложение в корне:
1 2 3 4 5 |
|
Пока вы этого не сделаете, ничего не будет отображаться.
Я получаю ошибку: "Target container is not a DOM element"¶
Эта ошибка означает, что все, что вы передаете в createRoot
, не является узлом DOM.
Если вы не уверены в том, что происходит, попробуйте записать лог:
1 2 3 4 |
|
Например, если domNode
равен null
, это означает, что getElementById
вернул null
. Это произойдет, если в документе нет узла с заданным ID на момент вашего вызова. Причин может быть несколько:
- Идентификатор, который вы ищете, может отличаться от идентификатора, который вы использовали в HTML-файле. Проверьте, нет ли опечаток!
- Тег
<script>
вашего пакета не может "увидеть" узлы DOM, которые появляются после него в HTML.
Другой распространенный способ получить эту ошибку - написать createRoot(<App />)
вместо createRoot(domNode)
.
Я получаю ошибку: "Функции не действительны как дочерние React"¶
Эта ошибка означает, что все, что вы передаете в root.render
, не является компонентом React.
Это может произойти, если вы вызываете root.render
с Component
вместо <Component />
:
1 2 3 4 5 |
|
Или если вы передаете функцию в root.render
, а не результат ее вызова:
1 2 3 4 5 |
|
Мой серверный рендеринг HTML создается заново¶
Если ваше приложение рендерится на сервере и включает первоначальный HTML, сгенерированный React, вы можете заметить, что создание корня и вызов root.render
удаляет весь этот HTML, а затем заново создает все узлы DOM с нуля. Это может быть медленнее, сбрасывает фокус и позиции прокрутки, а также может потерять другие пользовательские данные.
Приложения с серверным рендерингом должны использовать hydrateRoot
вместо createRoot
:
1 2 3 4 |
|
Обратите внимание, что его API отличается. В частности, обычно не происходит дальнейшего вызова root.render
.
Источник — https://react.dev/reference/react-dom/client/createRoot