【问题标题】:When to use React 16 Portals何时使用 React 16 门户
【发布时间】:2023-03-31 05:29:01
【问题描述】:

React 16 发布了许多新功能。其中之一是 ReactDOM.createPortal(child, container) API,它可以方便地从视觉上突破其容器。

然而,它似乎不仅打破了它的容器,而且打破了我从 Web 开发的第一天学到的基本 html 规则。 createPortal API 让您可以在父组件之外渲染组件,并打破我们预期的 html 结构约定。

另一方面,我们确实获得了更大的灵活性,现在可以在兄弟组件或其他组件中渲染 DOM。

IMO,我认为通过交易 html 约定来获得更多灵活性并不是一个好交易。官方提供的 example 也不能说服我。

我很好奇的是: 是否有人面临必须使用 createPortal API 的任何条件?

谢谢

【问题讨论】:

标签: html reactjs


【解决方案1】:

文档中的示例是 createPortal 真正有用的一些情况 - 特别是对话框、悬停卡和工具提示。

docs还特意声明:

注意:

请务必记住,在使用门户网站时,您需要确保遵循正确的可访问性指南。

例如,文档show how a modal 可以使用createPortal() 构建。您会注意到模式是在#modal-root 元素中创建的,它是#app-root 元素旁边的根元素。这是一个很好的例子,说明如何在不违反任何 HTML 规则的情况下使用 createPortal()

<div id="app-root"></div>
<div id="modal-root"></div>

【讨论】:

    【解决方案2】:

    几个月前我遇到了另一个用例。因为 React 16 门户不可用,我不得不使用自制的门户实现。

    我正在创建 SVG 图表。所有的线条、路径等都需要在&lt;svg&gt; 元素中呈现。但我想使用 HTML 来呈现文本标签(出于多种原因)。这意味着图上的对象及其标签必然位于 DOM 的不同部分。但是有了门户,我仍然可以将所有图形组件的逻辑放在一起。这是一个虚构的例子:

    const LabeledPoint = ({ x, y, r, labelText }) => [
        <circle cx={x} cy={y} r={r} />,
        <GraphLabel x={x + 5} y={y}>{labelText}</GraphLabel>,
    ];
    

    您将在 &lt;svg&gt; 元素中使用此组件。 GraphLabel 组件将使用门户在与 &lt;svg&gt; 相同的坐标处呈现 HTML div 元素中的 labelText,使用绝对定位将其放置在正确的坐标处。

    这样,单个组件的所有逻辑都可以放在一个地方,即使我出于技术原因需要在不同的地方渲染实际的 DOM 元素。

    【讨论】:

    • 谢谢,这是迄今为止我遇到的最好的实用示例
    【解决方案3】:

    当您需要在父组件的 DOM 层次结构之外渲染组件时,门户是非常有用的功能。

    您使用以下语法定义门户:

    ReactDOM.createPortal(child, container) 
    

    第一个参数 (child) 是任何可渲染的 React 子节点,例如 元素、字符串或片段。第二个参数(容器)是一个 DOM 元素。

    请参阅以下教程以了解如何以及为何使用门户:

    https://www.youtube.com/watch?v=lOMU9BeIrO4

    【讨论】:

      猜你喜欢
      • 2018-03-20
      • 1970-01-01
      • 2018-03-12
      • 2018-06-14
      • 2018-03-05
      • 2023-02-04
      • 2019-05-15
      • 1970-01-01
      • 2017-08-08
      相关资源
      最近更新 更多