React Portal 提供了一种将子节点渲染到父组件以外的 DOM 节点的优良解决方案。Portal 的最常见用例是子组件须要从视觉上脱离父容器,如下所示。
- 模态对话框
- 工具提醒
- 悬浮卡
- 加载动画
能够应用 ReactDOM.createPortal(child,container)
创立一个 Portal。这里的 child 是一个 React 元素,fragment 片段或者是一个字符串,container 是 Portal 要插入的 DOM 节点的地位。
上面是应用 ReactDOM.createPortal(child,container)
创立的一个简略 modal 组件。
const Modal = ({message, isOpen, onClose, children}) => {if (!isOpen) return null;
return ReactDOM.createPortal(
<div className="modal">
<span className="message">{message}</span>
<button onClick={onClose}>Close</button>
</div>,
domNode
);
};
即便 Portal 是在父级 DOM 元素之外出现的,他的体现行为也跟平时咱们在 React 组件中应用是一样的。它可能承受 props 以及 context API。这是因为 Portal 驻留在 React Tree 层次结构内(也就是保障在同一颗 React Tree 上)。
为什么咱们须要它呢
当咱们在特定元素(父组件)中应用模态弹窗时,模态的高度和宽度就会从模态弹窗所在的组件继承,也就是说模态弹窗的款式可能会被父组件影响。传统的模态框需将须要 CSS 属性,例如 overflow:hidden
和 z-index
来防止这个问题。
下面的代码示例将导致模态框在 root
下的嵌套组件外部渲染。当应用浏览器查看元素时,如下所示。
接下来,让咱们看看 React Portal 是如何被应用的。上面的代码应用 createPortal() 在 root 树层次结构之外创立 DOM 节点来解决此问题。
const Modal = ({message, isOpen, onClose, children}) => {if (!isOpen) return null;
return ReactDOM.createPortal(
<div className="modal">
<span>{message}</span>
<button onClick={onClose}>Close</button>
</div>,
document.body
);
};
function Component() {const [open, setOpen] = useState(false);
return (
<div className="component">
<button onClick={() => setOpen(true)}>Open Modal</button>
<Modal
message="Hello World!"
isOpen={open}
onClose={() => setOpen(false)}
/>
</div>
);
}
上面显示的是 DOM 树层次结构,这是在应用 React Portal 时失去的,其中模态框组件将被注入 root 之外,并且与 root 处于同一层级。
因为这个模态框是在根层次结构之外渲染的,因而模态框的大小不会因为继承父级组件而被更改。
你可在 CodeSandbox 中找到这个例子,你能够在其中查看并批改代码以查看门户的工作形式,并解决咱们探讨的问题。
什么时候应用 Portal 呢
应用 React Portal 时,你应该留神几个方面。除非你理解 React Portal,否则上面这些行为不容易被觉察。因而,在这里提及。
- 事件冒泡会失常工作 —— 通过将事件流传到 React 树的先人,事件冒泡将按预期工作,而与 DOM 中的 Portal 节点地位无关。
- React 能够管制 Portal 节点及其生命周期 — 当通过 Portal 渲染子元素时,React 依然能够管制它们的生命周期。
- React Portal 只影响 DOM 构造 —— Portal 只会影响 HTML DOM 构造,而不会影响 React 组件树。
- 预约义的 HTML 挂载点 —— 应用 React Portal 时,你须要提前定义一个 HTML DOM 元素作为 Portal 组件的挂载。
论断
在咱们须要在失常 DOM 层次结构之外出现子组件而又不通过 React 组件树层次结构毁坏事件流传的默认行为时,React Portal(传送门)会派上用场。比方在渲染模态框,工具提醒,弹出音讯之类的组件时,这很有用。
你能够在 React 官网文档中找到更多对于 Portal 的形容。
感激你抽出工夫来浏览本文。我想在上面的评论局部中能看到你对这个主题的问题和评论。
???? 明天的文章分享就到这里啦,如果喜爱这篇文章的话请点赞、Star、关注我吧 ????
- 译者:NieZhuZhu(弹铁蛋同学)
- 校对者:zenblo
- 原文地址:Understanding React Portals
- 原文作者:Madushika Perera
- 译文出自:掘金翻译打算
- 本文永恒链接:https://github.com/xitu/gold-miner/blob/master/article/2020/understanding-react-portals.md