Порталы¶
Порталы позволяют рендерить дочерние элементы в DOM-узел, который находится вне DOM-иерархии родительского компонента.
1 |
|
Первый аргумент (child
) — это любой React-компонент, который может быть отрендерен, такой как элемент, строка или фрагмент. Следующий аргумент (container
) — это DOM-элемент.
Применение¶
Обычно, когда вы возвращаете элемент из рендер-метода компонента, он монтируется в DOM как дочерний элемент ближайшего родительского узла:
1 2 3 4 5 6 7 8 |
|
Но иногда требуется поместить потомка в другое место в DOM:
1 2 3 4 5 6 7 8 |
|
Типовой случай применения порталов — когда в родительском компоненте заданы стили overflow: hidden
или z-index
, но вам нужно чтобы дочерний элемент визуально выходил за рамки своего контейнера. Например, диалоги, всплывающие карточки и всплывающие подсказки.
Примечание:
При работе с порталами, помните, что нужно уделить внимание управлению фокусом при помощи клавиатуры.
Для модальных диалогов, убедитесь, что любой пользователь будет способен взаимодействовать с ними, следуя практикам разработки модальных окон WAI-ARIA.
Всплытие событий через порталы¶
Как уже было сказано, портал может находиться в любом месте DOM-дерева. Несмотря на это, во всех других аспектах он ведёт себя как обычный React-компонент. Такие возможности, как контекст, работают привычным образом, даже если потомок является порталом, поскольку сам портал всё ещё находится в React-дереве, несмотря на его расположение в DOM-дереве.
Так же работает и всплытие событий. Событие, сгенерированное изнутри портала, будет распространяться к родителям в содержащем React-дереве, даже если эти элементы не являются родительскими в DOM-дереве. Представим следующую HTML-структуру:
1 2 3 4 5 6 |
|
Родительский
компонент в #app-root
сможет поймать неперехваченное всплывающее событие из соседнего узла #modal-root
.
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
|
Перехват событий, всплывающих от портала к родительскому компоненту, позволяет создавать абстракции, которые не спроектированы специально под порталы. Например, вы отрендерили компонент <Modal />
. Тогда его события могут быть перехвачены родительским компонентом, вне зависимости от того, был ли <Modal />
реализован с использованием порталов или без них.