Portals提供了一种能让子节点渲染到父组件之外的方式。
React.createPortal(child,container);
第一个参数(child
)是任何可渲染的 React 子元素,例如一个元素,字符串或碎片。第二个参数(container
)则是一个 DOM 元素。
用法
当你从组件的render中返回一个元素,改元素节点只能装配置在dom结构下,距离他最近的父元素中。
render() {
// React mounts a new div and renders the children into it
return (
<div>
{this.props.children}
</div>
);
}
然而有时候把它插入到不同的DOM节点位置也是可以的。
render() {
// React does *not* create a new div. It renders the children into `domNode`.
// `domNode` is any valid DOM node, regardless of its location in the DOM.
return ReactDOM.createPortal(
this.props.children,
domNode,
);
}
使用portals
一个典型的案例就是:
当父组件有overflow
,z-index
样式的时候,但是你需要子组件在视觉上能够跳出容器,也就是说能显示出来。比如对话框,提示框等。
注意:
记住这点非常重要,当在使用 portals
时,你需要确保遵循合适的可访问指南。
通过portals进行事件冒泡
portal可以被放在DOM树的任何地方,但是在其他方面的行为与普通的React子节点是一致的。如上下文特性依然可以正确的工作。无论其子节点是否是 portal,由于 portal 仍存在于 React 树中,而不用考虑其在 DOM 树中的位置。
这包含事件树冒泡,一个从 portals 内部触发的事件将会一致冒泡到React的祖先。假设如下的HTML结构。
<html>
<body>
<div id="app-root"></div>
<div id="modal-root"></div>
</body>
</html>
app-root 里的 Parent 组件能够捕获到未被捕获的从兄弟节点 modal-root 冒泡上来的事件。
网友评论