当前位置: 首页 > Web前端 > HTML

你真的了解React门户吗?

时间:2023-04-02 14:54:27 HTML

以前写globalmask的时候一般都是固定定位。示例代码如下:.modal{position:fixed;左:0;右:0;顶部:0;底部:0;z-指数:500;background:black;}这样就实现了全局遮罩层,自己控制modal中的内容。但是这种方式会有一个问题,具体如下:可以看到这个弹窗的内容不在body下面的层中,而是在逐层嵌套的dom中,其中会有两个缺点:DOM结构不够优雅。组件的样式可能会影响子组件的样式。这是一个真实的案例。我同事也用上面固定定位的方式生成了一个全局弹窗,但是发现点击按钮不能改变弹窗的显示,然后发现他写了一个奇怪的。代码大致如下:return()and然后我发现点击这个按钮是不能控制modal的显示和隐藏的,因为这个按钮严重影响了modal的行为。这种问题其实很难排查。你不知道用户写了什么奇怪的代码。这时候考虑其他的方法来避免这个问题。当用户使用modal时,modal的DOM实际上是挂载在当前组件下的。试想一下,如果直接将DOM插入到body中,是否可以避免这些问题。幸运的是,React提供了这样的能力。下面介绍一下React提供了什么。引入PortalPortal,将子组件渲染到父组件以外的DOM节点。Portal可以将子组件渲染到DOM树而不是父组件。通常用于子组件需要从父组件的容器中分离出来的场景。有以下场景:Dialog对话框Tooltip文字提示Popover弹出框Loader全局加载器下面是它的使用方法:React.createPortal();第一个参数(child)是任何可渲染的React子元素,例如元素、字符串或片段。第二个参数(容器)是一个DOM元素。这是一个使用react.createPortal的简单示例:constModal=({message,visible,onClose,children})=>{if(!visible)returnnull;returnReactDOM.createPortal({message}Close

,domNode)}虽然portal超出了父组件的容器限制,其性能与普通React组件一致。它还可以接收道具和上下文。这是因为门户仍然存在于React层次结构中。为什么我们需要门户网站?就像文章开头提到的案例,我们需要在某个组件中使用模态弹窗。大多数情况下,我们可以使用固定定位来全局显示这个弹窗,但是在特殊情况下,这个模态弹窗可能会显示异常。所以这时候如果我们用传送门的方式,直接将modal的dom结构和父组件的容器分离,就可以避免这个问题。constModal=({message,isOpen,onClose,children})=>{if(!isOpen)返回空;返回ReactDOM.createPortal({message}Close
,document.body)}functionComponent(){const[open,setOpen]=useState(false)return(setOpen(true)}>setOpen(false)}/>
)}上面的代码可以保证无论子组件嵌套多深,modal都能和根。使用chrome查看DOM结构,可以看到如下结构使用了Portal。在使用Portal时需要知道,虽然Portal可以放在DOM树的任意位置,但它的行为与普通的React组件是一致的。由于门户仍然存在于React树中,无论它在DOM树中的位置如何,因此无论其子项是否为门户,上下文等功能都保持不变。这里有一些笔记可以总结一下。事件冒泡:从门户内部触发的事件将冒泡到包含React树中的祖先,即使这些元素不是DOM树中的祖先。生命周期:即使是通过Portal创建的元素,这个元素还是有它的生命周期的,比如componentDidMount等。影响范围:Portal只影响HTML的结构,不影响React树结构。挂载节点:使用Portal时必须定义一个真实的DOM节点作为Portal组件的挂载入口组件树层次结构,这在弹窗、提示等渲染中非常有用。欢迎关注“前端学习”,让前端学习不迷路或加微信ssdwbobo一起交流学习