createPortal¶
createPortal
позволяет вам выводить некоторые дочерние элементы в другую часть DOM.
1 2 3 4 |
|
Описание¶
createPortal(children, domNode, key?)
¶
Чтобы создать портал, вызовите createPortal
, передав некоторый JSX и DOM-узел, в котором он должен быть отображен:
1 2 3 4 5 6 7 8 9 10 11 |
|
Портал изменяет только физическое размещение узла DOM. Во всех остальных отношениях JSX, который вы отображаете в портал, действует как дочерний узел компонента React, который его отображает. Например, дочерний узел может получить доступ к контексту, предоставляемому родительским деревом, а события передаются от дочерних узлов к родительским в соответствии с деревом React.
Параметры
-
children
: Все, что может быть отображено с помощью React, например, фрагмент JSX (т. е.<div />
или<SomeComponent />
), Fragment (<>...</>
), строка или число, или массив из них. -
domNode
: Некоторый узел DOM, например, возвращаемыйdocument.getElementById()
. Узел должен уже существовать. Передача другого узла DOM во время обновления приведет к тому, что содержимое портала будет создано заново. -
опционально
key
: Уникальная строка или число, которое будет использоваться в качестве ключа портала.
Возвращает
createPortal
возвращает узел React, который может быть включен в JSX или возвращен из компонента React. Если React встретит его в выводе рендера, он поместит предоставленные children
внутрь предоставленного domNode
.
Предупреждения
- События от порталов распространяются в соответствии с деревом React, а не с деревом DOM. Например, если вы щелкните внутри портала, а портал обернут в
<div onClick>
, то сработает обработчикonClick
. Если это вызывает проблемы, либо остановите распространение событий внутри портала, либо переместите сам портал вверх в дереве React.
Использование¶
Рендеринг в другую часть DOM¶
Порталы позволяют вашим компонентам рендерить некоторые из своих дочерних компонентов в другое место в DOM. Это позволяет части вашего компонента "вырваться" из контейнеров, в которых он может находиться. Например, компонент может отображать модальный диалог или всплывающую подсказку, которая появляется над и вне остальной части страницы.
Чтобы создать портал, отобразите результат createPortal
с некоторым JSX и узлом DOM, где он должен быть размещен:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
React поместит DOM-узлы для переданного вами JSX внутрь предоставленного вами DOM-узла.
Без портала второй p
был бы помещен внутрь родительского div
, но портал "телепортировал" его в document.body
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Обратите внимание, что второй абзац визуально появляется вне родительского div
с границей. Если вы просмотрите структуру DOM с помощью инструментов разработчика, вы увидите, что второй p
был помещен непосредственно в body
:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Портал изменяет только физическое размещение узла DOM. Во всех остальных отношениях JSX, который вы отображаете в портал, действует как дочерний узел компонента React, который его отображает. Например, дочерний узел может получить доступ к контексту, предоставляемому родительским деревом, а события по-прежнему передаются от дочерних узлов к родительским в соответствии с деревом React.
Рендеринг модального диалога с помощью портала¶
Вы можете использовать портал для создания модального диалога, который парит над остальной частью страницы, даже если компонент, вызывающий диалог, находится внутри контейнера с overflow: hidden
или другими стилями, которые мешают диалогу.
В этом примере два контейнера имеют стили, которые мешают модальному диалогу, но тот, который отображается в портале, не затронут, потому что в DOM модальный диалог не содержится в родительских JSX-элементах.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
1 2 3 4 5 6 7 8 |
|
Важно убедиться, что ваше приложение доступно при использовании порталов. Например, вам может понадобиться управлять фокусом клавиатуры, чтобы пользователь мог перемещать фокус в портал и из него естественным образом.
При создании модалов следуйте WAI-ARIA Modal Authoring Practices. Если вы используете пакет сообщества, убедитесь, что он доступен и следует этим рекомендациям.
Рендеринг компонентов React в серверную разметку, не относящуюся к React¶
Порталы могут быть полезны, если ваш React root является лишь частью статической или серверной страницы, построенной не на React. Например, если ваша страница построена на серверном фреймворке, таком как Rails, вы можете создавать интерактивные области внутри статичных областей, таких как боковые панели. По сравнению с наличием нескольких отдельных корней React, порталы позволяют рассматривать приложение как единое дерево React с общим состоянием, даже если его части отображаются в разных частях DOM.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
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 |
|
Рендеринг компонентов React в не-React DOM-узлы¶
Вы также можете использовать портал для управления содержимым DOM-узла, который управляется вне React. Например, предположим, что вы интегрируетесь с виджетом карты, не принадлежащим React, и хотите отобразить содержимое React во всплывающем окне. Чтобы сделать это, объявите переменную состояния popupContainer
для хранения DOM-узла, в который будет производиться рендеринг:
1 |
|
Когда вы создаете сторонний виджет, сохраните узел DOM, возвращаемый виджетом, чтобы вы могли выполнить в нем рендеринг:
1 2 3 4 5 6 7 8 |
|
Это позволит вам использовать createPortal
для рендеринга React-контента в popupContainer
, как только он станет доступен:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Вот полный пример, с которым вы можете поиграть:
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 35 36 37 38 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Источник — https://react.dev/reference/react-dom/createPortal