将React门户呈现到另一个组件DOM中是否安全?

Lui*_*lgo 4 javascript reactjs react-dom

考虑以下示例:

class GridContainer extends React.Component {
  ...
  render (){
    return <div>
      <Pagination portalId="portal-id"></>
      <Grid ...>
    </div>
  }
}

class Grid extends React.Component {
  ...
  render (){
    return <div>
      <div id="portal-id"></>
      <table ...>
    </div>
  }
}

class Pagination extends React.Component {
  ...
  render (){
    return return ReactDOM.createPortal(<div>Paginator DOM...</div>, document.getElementById(this.props.portalId));
  }
}
Run Code Online (Sandbox Code Playgroud)

在其他组件DOM中呈现门户是否安全?我已经对其进行了测试,但是它不可靠。该Portals文档提到您可以在DOM节点中呈现门户,但是与组件DOM无关。

为什么这有所不同(在这里推测)?在更新门户网站父级组件时,在对帐过程中,差异可能会发现不一致之处并删除门户网站节点。

从我的测试来看,上述情况没有发生,但我不知道我是否可以假设React可以处理。问:

将门户呈现到另一个组件DOM中是否安全?

Est*_*ask 7

Portals 文档提到您可以在 DOM 节点中渲染门户,但没有提到组件 DOM

没有提到这一点,因为这是一般规则的特殊情况;如果有更惯用的方式,则不应在 React 中直接访问 DOM。

DOM 中发生了大量的内存泄漏。如果承载门户 ( Grid) 的组件被重新渲染,而门户组件 ( Pagination) 没有被重新渲染,这将导致 DOM 分离,即内存泄漏。

当门户组件呈现时,附加门户的元素甚至可能不存在。


R E*_*ond 6

安全吗?当然可以,但可能无法达到您的预期。

首先,您可以将dom完全转储div到React创建的dom中。

我遇到了几个会反驳这个事实的React程序员,但是Reacts设计期望并在必要时直接编辑dom。如果没有,就不会有componentDidUpdateReact refs

与其他库集成的本文档可能是最相关的。

这是独家新闻:

  • 假设在渲染结束时始终为空,React不会接触已渲染div的内部。它只会:
    • 创建新元素,只要您将其保留为空,就在这里无关紧要。
    • 更新最初由react创建的现有元素。
    • 删除最初由react创建的元素。

因此,只需创建一个空的div并将其保留render,React就不会搞乱它。

这是磨擦;React不能保证渲染的时间。

这意味着您不知道该元素在Pagination渲染时是否会真正存在,从而导致查询失败并且门户不会显示。componentDidUpdate只起作用,因为React 是在dom更新专门运行它的。但是渲染是 dom更新之前运行的。因此,如果Pagination在与Grid该div 相同的扫描中渲染if ,则可能尚未挂载。

现在臭名昭著的堆栈溢出了“不要做”的答案:

只是不要那样做。门户的目的是让您在React容器外进行渲染,同时将组件保持在Reacts渲染树中。如果您仍然在React渲染树中进行渲染,为什么不只是在那里渲染组件呢?(如果那句话令人困惑,我要怪你)