• React Portal的用法
  • 发布于 2个月前
  • 362 热度
    0 评论
  • Scys
  • 5 粉丝 38 篇博客
  •   
React Portal提供了将子节点渲染到父组件以外的DOM节点的解决方案。Portal常用于帮助子节点“跳出”当前父容器,从而避免被当前父容器的节点位置以及CSS属性等影响,因此日常开发中,mask、dialog、toast等的实现,都可以直接使用Portal。
createPortal接收三个参数:要渲染的子节点,指定的DOM节点和可选的键值(key)。然后React会创建一个新的React Portal对象,该对象包含以下属性:
• $$typeof:标识该对象为React Portal
• key:Portal的键值
• children:要渲染的子节点
• containerInfo:指定的DOM节点
• implementation:Portal的实现
function createPortal(
  children: ReactNodeList,
  container: Container,
  key: ?string = null,
): ReactPortal {
  return {
    // This tag allow us to uniquely identify this as a React Portal
    $$typeof: REACT_PORTAL_TYPE,
    key: key == null ? null : '' + key,
    children,
    containerInfo: getContainer(container),
    implementation: null,
  };
}

React Portal是一种特殊的React元素,它具有独特的类型标识符REACT_PORTAL_TYPE,此外,Portal还需要一个指向实际DOM节点的引用,这个引用可以通过containerInfo属性获取。React Portal的渲染是通过ReactDOM.render方法实现的,具体的渲染过程与普通的React元素相同,只是将渲染结果插入到Portal的指定DOM节点中,而不是插入到根节点中。


在Portal渲染之前,还需要将Portal元素从其父元素的子节点列表中移除。这是通过ReactChildReconciler模块中的moveChild方法实现的。移除操作完成后,Portal元素的containerInfo属性将被设置为null,以便在Portal被卸载时清除对DOM节点的引用。

使用Portal需要注意以下事项:

• creactPortal的冒泡依然存在。creactPortal与render不同,React Portal 之所以能够保留事件冒泡行为,是因为 Portal 并不是在全局创建一个独立的 DOM 节点,而是将组件的子树渲染到了指定的目标 DOM 节点中。因此,这些组件仍然保留了事件冒泡行为。


• React Portal 的生命周期可以通过创建 Portal 时指定的目标 DOM 容器的生命周期来控制。具体来说,在 Portal 的目标 DOM 容器的生命周期中,会触发 Portal 组件的生命周期方法,从而实现对 Portal 生命周期的控制。 例如,假设有一个包含一个 Portal 的父组件 ParentComponent,当 ParentComponent 被挂载时,Portal 组件的 componentDidMount() 生命周期方法也会被触发,而当 ParentComponent 被卸载时,Portal 组件的 componentWillUnmount() 生命周期方法也会被触发。
• 谨慎使用CSS。css的作用域是全局,通过Portal移动的的子元素依然会受CSS的影响。当父容器进行替换以后,加大了样式会覆盖别的地方的样式或是在新的父节点上被其他样式影响的可能性。正常情况下,我们希望一个样式只适用于单个对应的组件,所以为了避免样式混乱,建议portal使用module.css或是scss。
用户评论