我正在使用React 16,并且需要门户网站,但是无法找到有关此功能的任何文档。有人知道怎么使用吗?
https://github.com/facebook/react/pull/10675
感谢您的任何建议。
React v16刚刚发布了几个小时(正式版),正式支持Portal。
Portal
什么是门户? 到现在已经有多久了?
门户网站提供了一种一流的方式来将子级呈现到父组件的DOM层次结构之外的DOM节点中。
Portal在React社区中不是新概念。有许多支持这种功能的库。例如react- portal和react- gateway。
呈现任何React应用时会发生什么?
通常,在渲染任何React应用程序时,单个DOM元素用于渲染整个React树。
class HelloReact extends React.Component { render() { return ( <h1>Hello React</h1> ); } } ReactDOM.render(<HelloReact />, document.getElementById('root'));
如您所见,我们正在将我们的react组件渲染为一个具有id的DOM元素root。
root
什么是门户网站?为什么需要门户网站? 为什么在那儿?
门户网站是一种在父组件的主DOM层次结构之外呈现React子代 而又不会丢失react上下文的方法 。我强调这一点是因为非常流行的库,例如react-router,redux大量使用了react上下文。因此,使用时的上下文可用性Portal非常有帮助。
根据反应文档,
门户的典型用例是父组件发生溢出:隐藏或z-index样式,但是您需要子组件以可视方式“脱离”其容器。例如,对话框,悬浮卡和工具提示。
因此,使用门户网站时,您可以在需要时将并行反应树渲染到另一个DOM节点上。即使将其呈现在不同的DOM节点中,父组件也可以捕获未捕获的事件。请参阅文档本身中提供的此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 inspect元素,查看<h1>I am rendered through a Portal.</h1>在#another-root标签内部呈现的元素,而<h1>Hello World</h1>在#root标签内部呈现的元素。
<h1>I am rendered through a Portal.</h1>
#another-root
<h1>Hello World</h1>
#root
希望这可以帮助 :)
更新 :回答@PhillipMunin的评论。
ReactDOM.render和 之间有什么区别ReactDOM.createPortal?
ReactDOM.render
ReactDOM.createPortal
即使通过门户网站呈现的组件已呈现在其他位置(当前容器根外部),它仍作为同一父组件的子组件存在。(谁调用ReactDOM.createPortal),因此子级上的所有事件都将传播到父级。(Ofc,如果您手动停止事件的传播,则此方法无效。)
通过门户网站呈现的组件内部可以访问相同的上下文。但是,如果我们ReactDOM.render直接这样做,情况并非如此。
我创建了另一个演示来说明我的观点。https://codesandbox.io/s/42x771ykwx