Я использую React 16 и нуждаюсь в порталах, но не могу найти никакой документации по этой функции. Кто-нибудь знает, как использовать это еще?
https://github.com/facebook/react/pull/10675
Спасибо за любой совет.
Я использую React 16 и нуждаюсь в порталах, но не могу найти никакой документации по этой функции. Кто-нибудь знает, как использовать это еще?
https://github.com/facebook/react/pull/10675
Спасибо за любой совет.
React v16 только что выпустил пару часов назад (Yay!!), который официально поддерживает Portal
.
Что такое портал? Так как долго он там был?
Порталы предоставляют первоклассный способ отображения дочерних элементов в DOM node, который существует вне иерархии DOM родительского компонента.
Portal
не является новой концепцией в сообществе реагирования. Доступны многие библиотеки, поддерживающие такую функциональность. например react-portal и react-gateway.
Что происходит при рендеринге любого реагирующего приложения?
Как правило, при рендеринге любого приложения React для создания всего дерева React используется один элемент DOM.
class HelloReact extends React.Component {
render() {
return (
<h1>Hello React</h1>
);
}
}
ReactDOM.render(<HelloReact />, document.getElementById('root'));
Как вы можете видеть, мы превращаем наш реагирующий компонент в элемент DOM с идентификатором root
.
Что такое портал и зачем он нужен? Почему он там?
Порталы - это способ рендерить детей React из основной иерархии DOM родительского компонента без потери контекста реакции. Я подчеркиваю это потому, что очень популярные библиотеки, такие как react-router, redux сильно использует контекст реакции. Таким образом, контекстная доступность при использовании Portal
очень полезна.
В соответствии с react docs,
Типичный вариант использования порталов - это когда родительский компонент имеет переполнение: скрытый или z-индексный стиль, но вам нужно, чтобы ребенок визуально "разрывался" в своем контейнере. Например, диалоги, наводки и всплывающая подсказка.
Итак, с порталами вы можете визуализировать дерево с параллельным реагированием на другой DOM node, когда это необходимо. Несмотря на то, что он отображается в разных DOM node, родительский компонент может поймать неотображаемые события. Смотрите codepen, предоставленный в самих документах.
Ниже приведен пример:
// index.html
<html>
<body>
<div id="root"></div>
<div id="another-root"></div>
</body>
</html>
// index.jsx
const mainContainer = document.getElementById('root');
const portalContainer = document.getElementById('another-root');
class HelloFromPortal extends React.Component {
render() {
return (
<h1>I am rendered through a Portal.</h1>
);
}
}
class HelloReact extends React.Component {
render() {
return (
<div>
<h1>Hello World</h1>
{ ReactDOM.createPortal(<HelloFromPortal />, portalContainer) }
</div>
);
}
}
ReactDOM.render(<HelloReact />, mainContainer);
https://codesandbox.io/s/62rvxkonnw
Вы можете использовать элемент проверки devtools и видеть, что <h1>I am rendered through a Portal.</h1>
отображается внутри тега #another-root
, тогда как <h1>Hello World</h1>
отображается внутри тега #root
.
Надеюсь, что это поможет:)
Обновить: ответить комментарий @PhillipMunin.
В чем разница между
ReactDOM.render
иReactDOM.createPortal
?
Несмотря на то, что компонент, отображаемый через портал, отображается где-то в другом месте (вне текущего корня контейнера), он остается в виде дочернего элемента того же родительского компонента. (Кто вызвал ReactDOM.createPortal
). Таким образом, любые события на дочернем сервере распространяются на родителя. (Ofc, это не работает, если вы вручную остановите распространение события.)
Тот же контекст доступен внутри компонента, отображаемого через портал. Но не в том случае, когда мы делаем ReactDOM.render
напрямую.
Я создал еще одну демонстрацию, чтобы проиллюстрировать мою мысль. https://codesandbox.io/s/42x771ykwx
Порталы создаются путем вызова метода createPortal
внутри метода render
вашего компонента.
render() {
return (
<div>
{ReactDOM.createPortal(this.renderPortal(), this.props.portalEl)}
</div>
)
}
renderPortal
должен возвращать содержимое, которое будет отображаться внутри портала, а portalEl
- это внешний элемент DOM, который получит контент.
Кто-то недавно рассказал об этой информации на порталах в React tests.