Источник: Nuances of Programming
Согласно официальной документации по React, порталы представляют собой первоклассный способ отображения дочерних компонентов в узел DOM вне DOM-иерархии родительского компонента, определяемой иерархией дерева компонентов. Порталы применяют в ситуациях, когда необходимо, чтобы дочерние компоненты визуально вырывались из родительского контейнера. Типичные примеры использования порталов:
- Модальные диалоговые окна.
- Всплывающие подсказки.
- Всплывающие визитки.
- Загрузчики.
Портал создаётся с помощью ReactDOM.createPortal(child, container). Здесь child — это элемент, фрагмент или строка React, а container— это местоположение или узел DOM, в который должен добавляться портал.
Вот пример компонента modal, созданного с использованием приведённого выше API:
Несмотря на то, что портал отображается вне родительского элемента DOM, ведёт он себя аналогично обычному компоненту React внутри приложения. Он может получить доступ к props и context API. Почему? Потому что портал находится внутри иерархии дерева React.
С реальным примером порталов в React можно ознакомиться в этом компоненте, выложенном в разделе компонентов на сайте Bit (вы тоже можете задействовать этот сайт для выкладывания там компонентов и повторного их использования):
Для чего нужны порталы
При использовании modal внутри конкретного элемента (родительского компонента) высота и ширина этого modal будут унаследованы от компонента, в котором находится modal. Поэтому есть вероятность того, что modal будет «обрезан», вследствие чего он будет неправильно отображаться в приложении. Во избежание этой проблемы традиционному modal потребуются такие свойства стиля CSS, как overflow:hidden и z-index.
В результате приведённого выше примера кода, modal будет отображён в root внутри вложенных компонентов. При просмотре кода приложения в браузере с помощью функции inspect элементы будут показаны следующим образом:
Посмотрим, как нам здесь задействовать портал React. Следующий код решает этот вопрос через createPortal()для создания DOM-узла вне иерархии root:
Ниже показана иерархия дерева DOM, которая будет получена при использовании порталов React. В ней modal будет добавлен вне root, находясь с ним на одном уровне:
Размеры компонента modal не будут унаследованы или изменены родительскими компонентами, потому что он отображается вне корневой иерархии root.
Этот пример можно найти в CodeSandbox и поэкспериментировать с кодом, чтобы воочию убедиться в том, как работают порталы, и проработать рассмотренные нами вопросы.
Что надо учитывать при использовании порталов
Имея дело с порталами в React, надо помнить о нескольких вещах. Эти поведения не сразу заметишь, если они тебе не знакомы. Поэтому немного расскажем и о них тоже.
- Всплывающее событие будет работать, как обычно, распространяя события на предков в дереве React, независимо от местоположения узла портала в DOM.
- React контролирует узлы портала и его жизненный цикл при отображении дочерних элементов с помощью этих порталов.
- Порталы влияют только на структуру DOM для HTML и не затрагивают дерево компонентов React.
- Предварительно определяется точка монтирования HTML: при использовании порталов необходимо определить HTML-элемент DOM в качестве точки монтирования компонента портала.
Заключение
Порталы в React могут пригодиться, когда необходимо отобразить дочерние компоненты вне обычной иерархии DOM. При этом используется иерархия дерева компонентов React и не нарушается поведение по умолчанию, определённое для распространения событий. Таким образом отображаются такие компоненты, как modal, всплывающие подсказки или сообщения и многие другие.
Более подробная информация о порталах содержится в официальной документации React.
Спасибо за внимание!
Читайте также:
Перевод статьи Madushika Perera: Understanding React Portals and Its Use-Cases