为什么React 16中的碎片比容器div更好?

时间:2017-12-11 21:41:32

标签: reactjs

在React 16.2中,增加了对Fragments的改进支持。更多信息可以在React的博客文章here.

中找到

我们都熟悉以下代码:

render() {
  return (
    // Extraneous div element :(
    <div>
      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </div>
  );
}

是的,我们需要一个容器div,但这并不是什么大不了的事。

在React 16.2中,我们可以这样做以避免周围的容器div:

render() {
  return (
    <Fragment>
      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </Fragment>
  );
}

在任何一种情况下,我们仍然需要一个围绕内部元素的容器元素。

我的问题是,为什么使用Fragment更可取?它对性能有帮助吗?如果是这样,为什么?会喜欢一些见解。

6 个答案:

答案 0 :(得分:246)

  1. 它的速度更快,内存使用量更少(无需创建额外的DOM节点)。这仅对非常大和/或深的树木有实际好处,但应用性能通常会因千次切割而死亡。这减少了一个。
  2. 某些CSS机制(如Flexbox和CSS Grid)具有特殊的父子关系,并且在中间添加div会使得在提取逻辑组件时难以保持所需的布局。
  3. DOM检查器不那么混乱。 : - )
  4. 您可以在此React问题中找到其他一些用例的说明:https://github.com/facebook/react/issues/2127

答案 1 :(得分:19)

添加上述所有答案还有一个优势:代码可读性Fragment组件支持语法糖形式<>。因此,您的问题中的代码可以更容易地编写为:

render() {
  return (
    <>
      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </>
  );
}

根据docs

  

在React中,这会消除<React.Fragment/>元素,如上一节中的示例所示。 (使用JSX的非React框架可以编译为不同的东西。)

没有杂乱,对吧?

请注意,如果您需要向片段提供<Fragment>,仍需要使用key语法。

答案 2 :(得分:6)

  • 使用JSX
  • 添加了以前无法实现的功能
  • 更好的语义jsx标记。在需要时使用包装元素不是因为它们被迫使用。
  • 减少整体dom标记(提高渲染性能和减少内存开销)

就像你不需要包装元素一样简单,你不会被迫使用它。拥有较少的元素是很好的,但我认为最大的好处是能够在jsx中呈现以前不可能的元素,并为包装元素添加更好的语义含义,因为它们现在是可选的。

之前不可能:

 <select>
    {this.renderOptions()}
 </select>

在React 15中浏览以下内容,您无法判断是否需要包装元素:

<span>
  <h1>Hello</h1>
  {this.getContent()}
</span>

答案 3 :(得分:1)

  1. 使用<React.Fragment>...</React.Fragment>,我们可以在JSX元素中添加一个父标记,而无需在DOM中添加额外的节点。
  2. 您可以用React.Fragment替换多余的div标签
  3. 每次编写React.Fragment对您来说太长了。 React.Fragment具有可以使用的简写语法。是<>...</>.

答案 4 :(得分:0)

根据reatjs.org docs(而不是div),<Fragments> <Fragments/>的最重要需求是避免破坏HTML语义。当使用div代替<Fragments> <Fragments/>时,我们破坏了HTML语义。 进一步了解html语义。请click 并且在某些情况下,如果您使用div而不是Fragments,则它将是无效的html,例如,查看此代码。

class Columns extends React.Component {
  render() {
    return (
      <div>
        <td>Hello</td>
        <td>World</td>
      </div>
    );
  }
}
Result in table output of Columns Component  
<table>
      <tr>
        <div>
          <td>Hello</td>
          <td>World</td>
        </div>
      </tr>
 </table>

片段解决了这个问题。

答案 5 :(得分:0)

我更喜欢使用React.Fragment的简写版本

<>
   <p>....</p>
   <div>....</div>
</>

相同
<React.Fragment>
   <p>....</p>
   <div>....</div>
</React.Fragment>