React Portal 是一种优秀的方法,可以将子组件渲染到由组件树层次结构定义的父 DOM 层次结构之外的 DOM 节点中。Portal 的最常见用例是子组件需要从视觉上脱离父容器的情况,如下所示。
模态对话框
工具提示
悬浮卡片
加载器
可以使用 ReactDOM.createPortal(child, container)创建一个 Portal。这里的 child 是一个 React 元素、片段或字符串,而 container 是 Portal 应该注入到的 DOM 位置(节点)。
以下是使用上述 API 创建的一个示例模态(modal)组件。
即使 Portal 是在父 DOM 元素外部渲染的,其行为也类似于应用程序中的常规 React 组件。它可以访问 props 和 context API。这是因为 Portal 位于 React Tree 层次结构内。想要看一看 React Portal 的实践示例,请查看在 Bit 的组件中心上分享的这个组件(你也可以使用 Bit 共享和重用组件):
示例:使用 React Portal 的 React 组件——在 Bit.dev 上分享
我们为什么需要它?
当我们在特定元素(父组件)中使用模态时,模态的高度和宽度将从模态所在的组件继承。因此,模态可能会被裁剪,而无法在应用程序中正确显示。传统上模态需要 CSS 属性,如 overflow:hidden 和 z-index,以避免出现这一问题。
被父组件覆盖高度和宽度的一个典型模态
上面的代码示例将导致在根下的嵌套组件内部渲染这个模态。使用浏览器检查这个应用程序时,它将显示元素,如下所示。
没有 React Portal 的模态渲染
让我们看看如何在这里使用 React Portal。以下代码将使用 createPortal(),在 root 树层次结构之外创建一个 DOM 节点来解决这个问题。
下面显示的是一个 DOM 树层次结构,这是在使用 React Portal 时产生的,其中模态将被注入到 root 的外部,并与 root 处于同一级别。
使用 React Portal 渲染的模态
由于这个模态是在根层次结构之外渲染的,因此其尺寸不会被父组件继承或更改。
渲染为 Portal 的模型
你可以在这个 CodeSandbox 中找到这个示例,在其中可以试用代码、查看 Portal 的工作方式并解决所讨论的问题。
使用 Portal 时要注意的事项
使用 React Portal 时,你应该注意几个问题。下面提到的这些行为并不是直观可见的,你需要了解它们才行,因此我想在这里提一下。
事件冒泡(Event Bubbling)将照常工作:通过将事件传播到 React 树的祖先,事件冒泡将按预期工作,而与 DOM 中的 Portal 节点位置无关。
React 可以控制 Portal 节点及其生命周期:通过 Portal 渲染子元素时,React 仍然可以控制其生命周期。
Portal 仅影响 DOM 结构:Portal 仅影响 HTML DOM 结构,而不影响 React 组件树。
预定义 HTML 挂载点:使用 Portal 时,你需要定义一个 HTML DOM 元素作为 Portal 组件的挂载点。
小结
当我们需要在正常的 DOM 层次结构之外渲染子组件,而又不通过 React 组件树层次结构破坏事件传播的默认行为时,React Portal 就会派上用场。当渲染诸如模态、工具提示、弹出消息之类的组件时,它会很有用。
你可以在 React 官方文档中找到有关 Portal 的更多信息。
感谢阅读,请在下面的评论中分享你对这个主题的问题和评论,干杯!
原文链接:React Portals 简述及其用例
评论