react:<React.Fragment> 与数组

IT技术 reactjs
2021-05-13 04:39:24

我正在阅读 React 文档并被主题Fragments弄糊涂了既然我们基本上可以在 React 中返回一个数组,那么在什么情况下需要<Fragements />

这是一个代码示例:

const ReturnArray = () => {
  const items = [
    <div key={1}>Item 1</div>,
    <div key={2}>Item 2</div>,
    <div key={3}>Item 3</div>,
  ]
  return items
}

const ReturnFragments = () => {
  const items = 
    <React.Fragment>
      <div key={1}>Item 1</div>
      <div key={2}>Item 2</div>
      <div key={3}>Item 3</div>
    </React.Fragment>

  return items
}

我认为他们是一样的。

大多数现有的话题谈“键警告问题”像这样在github上,但我只是想知道的用例<Fragments />


编辑:

请告诉我是否有任何不明确的地方。

再具体一点:

请解释之间的差异<ReturnArray /><ReturnFragments />它们都返回多个没有无用<div>标签的元素为什么要费心使用额外的<React.Fragment />部分?

4个回答

官方文件

使用数组符号与普通的 JSX 有一些令人困惑的区别:

  1. 数组中的子项必须用逗号分隔。

  2. 数组中的子项必须有一个键来防止 React 的键警告。

  3. 字符串必须用引号括起来。

所以为了简单起见,React 提供了可以用来代替数组的 Fragment 组件。

考虑我们如何使用数组包装多个孩子

render() {
 return [
  "Some text.",
  <h2 key="heading-1">A heading</h2>,
  "More text.",
  <h2 key="heading-2">Another heading</h2>,
  "Even more text."
 ];
}

以及如何使用 Fragments 来实现。

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

直接取自官方文档。

片段也可以写成如下。

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

在 return 语句中使用 Fragment 而不是数组有两个主要优点

  1. 类似于其他组件的简单语法,因此您不必担心返回逗号分隔值、用引号括起字符串等
  2. 片段可以采用诸如键之类的属性,这在您从地图中返回数据时通常很重要。你不能使用数组来做到这一点。

例子

const ReturnFragments = () => {
  const items = list.map((item) => {
    <React.Fragment key={item.id}>
      <div key={1}>Item 1</div>
      <div key={2}>Item 2</div>
      <div key={3}>Item 3</div>
    </React.Fragment>
   })
  return items
}

片段和数组旨在解决不同的用例,并以一种重要的方式表现出不同的行为。

如果省略key属性,片段不会发出警告,而数组会。

如果您的组件返回多个静态子组件,则返回一个 fragment

<Fragment>
  <li>One advantage of our product is lorem</li>
  <li>Another is ipsum!</li>
</Fragment>

如果您的组件返回动态生成的子组件,请返回一个数组

items.map(item => <li key={item}>{item}</li>);

我正在解释维护者对我在 React 存储库中打开的关于类似问题的问题的回应。我强烈建议阅读它以获取更多详细信息:https : //github.com/facebook/react/issues/12776

创建新组件时,render 方法需要返回一个且仅一个元素,因此通常它是许多元素的包装器,而不是为 dom 创建无用的 div,您可以使用片段组件。

引自 React Fragments 文档:

React 中的一个常见模式是组件返回多个元素。Fragments 允许您对子项列表进行分组,而无需向 DOM 添加额外的节点。

无碎片

    render() {
      return {
       <div> ---> Useless root
          <div>fake</div>
          <div>fake</div>
          <div>fake</div>
       </div>
     }
}

带碎片

  render() {
      return {
       <React.Fragment> ----> Not rendered to the DOM
          <div>fake</div>
          <div>fake</div>
          <div>fake</div>
       </React.Fragment>
     }
   }