如何在React 16中使用ReactDOM.createPortal()? [英] How to use ReactDOM.createPortal() in React 16?

查看:189
本文介绍了如何在React 16中使用ReactDOM.createPortal()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用React 16并需要门户网站,但无法找到有关此功能的任何文档。有谁知道如何使用它?

I'm using React 16 and need portals, but am not able to find any documentation on this feature. Does anyone know how to use this yet?

https://github.com/facebook/react/pull/10675

感谢您的任何建议。

推荐答案

React v16刚刚发布了几个小时(Yay !!),正式支持 Portal

React v16 has just released a couple of hours ago (Yay!!) which officially supports Portal.

什么门户网站?它有多长时间了?


门户网站提供了一种将子节点呈现为存在的DOM节点的一流方法在父组件的DOM层次结构之外。

Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.

Portal 不是新概念在反应社区。许多库都支持这种功能。例如 react-portal react-gateway

Portal is not new concept in the react community. Many libraries are available that supports this kind of functionality. e.g react-portal and react-gateway.

呈现任何反应应用时会发生什么?

通常,在渲染任何React应用程序时,使用单个DOM元素来渲染整个React树。

Generally, when rendering any React application, a single DOM element is used to render the whole React tree.

class HelloReact extends React.Component {
   render() {
       return (
          <h1>Hello React</h1>
       );
   }
}

ReactDOM.render(<HelloReact />, document.getElementById('root'));

正如您所看到的,我们将react组件呈现为ID root 。

As you can see we are rendering our react component into a DOM element having id root.

什么是Portal,为什么需要它?为什么会出现?

门户网站是一种在父组件 的主DOM层次结构之外呈现React子元素的方法,而不会丢失反应背景 。我正在强调它,因为非常受欢迎的库,如 react-router redux 大量使用react上下文。因此,使用 Portal 时的上下文可用性非常有用。

Portals are a way to render React children outside the main DOM hierarchy of the parent component without losing the react context. I'm emphasizing on it because very popular libraries like react-router, redux heavily uses the react context. So context availability when using Portal is very helpful.

根据反应文档,


A门户网站的典型用例是当父组件具有溢出:隐藏或z-index样式时,但您需要子项在视觉上突破其容器。例如,对话框,悬停卡和工具提示。

A typical use case for portals is when a parent component has an overflow: hidden or z-index style, but you need the child to visually "break out" of its container. For example, dialogs, hovercards, and tooltip.

因此,使用门户,您可以将并行反应树渲染到另一个DOM节点上需要。即使它在不同的DOM节点中呈现,父组件也可以捕获未捕获的事件。请参阅文档中提供的 codepen

So, with portals, you can render a parallel react tree onto another DOM node when needed. Even though it is rendered in the different DOM node, parent component can catch the uncaught events. See this codepen provided in the docs itself.

以下示例应该提供更多想法:

The below example should give your more idea:

// 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> ;我通过Portal呈现。< / h1> #another-root 标记内呈现,而< ; h1> Hello World< / h1> #root 标记内呈现。

You can use devtools inspect element and see that <h1>I am rendered through a Portal.</h1> is rendered inside #another-root tag, whereas <h1>Hello World</h1> is rendered inside #root tag.

希望这会有所帮助:)

更新:回答 @ PhillipMunin的评论


ReactDOM.render
<$之间有什么不同? c $ c> ReactDOM.createPortal ?




  1. 尽管通过门户呈现的组件呈现在其他位置(在当前容器根目录之外),它仍然作为同一父组件的子项存在。 (谁调用 ReactDOM.createPortal )因此,子项上的任何事件都会传播到父项。 (Ofc,如果手动停止事件的传播,则不起作用。)

  1. Even though the component rendered through the portal is rendered somewhere else (Outside the current container root), it remains present as the child of the same parent component. (Who invoked the ReactDOM.createPortal) So any events on the child are propagated to the parent. (Ofc, This doesn't work if you manually stop the propagation of the event.)

在通过门户网站呈现的组件内可访问相同的上下文。但不是在我们直接 ReactDOM.render 的情况下。

Same context is accessible inside the component rendered through a portal. But not in the case when we do ReactDOM.render directly.

我已经创建了另一个演示来说明我的观点。 https://codesandbox.io/s/42x771ykwx

I've created another demo to illustrate my point. https://codesandbox.io/s/42x771ykwx

这篇关于如何在React 16中使用ReactDOM.createPortal()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆