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(
"modal">
"message">{message}
,
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(
"modal">
{message}
,
document.body
);
};
function Component() {
const [open, setOpen] = useState(false);
return (
"component">