reactjs - React中重复元素的 key 管理

标签 reactjs

我需要一个组件,给定一些子元素,它会一遍又一遍地重复这些子元素以填充屏幕。假设它有一个像这样的简单 Markdown :

<FillScreen items={[
    { id: 'one', content: 'foo' },
    { id: 'two', content: 'bar' }
]} />

在内部,该组件将获取屏幕尺寸,并最终用这些项目填充屏幕。生成的 DOM 将如下所示:

<div class="fill-screen">
   <div>foo</div>
   <div>bar</div>
   <div>foo</div>
   <div>bar</div>
   <div>foo</div>
   <div>bar</div>
   <div>foo</div>
</div>

我遇到的问题是,当这个元素计算出它需要渲染 7 个元素时,我不能直接使用 items[i].id 作为每个元素的键,因为会被重复的键。

我不确定解决这个问题的最佳模式是什么,我想到了两种可能的解决方案,但我并不完全喜欢:

解决方案A

在每个键上附加一个循环索引,因此渲染中的数组包含以下 JSX:

   <div key='one-0'>foo</div>
   <div key='two-0'>bar</div>
   <div key='one-1'>foo</div>
   <div key='two-1'>bar</div>
   <div key='one-2'>foo</div>
   <div key='two-2'>bar</div>
   <div key='one-3'>foo</div>

编辑 - 请注意,这些元素被生成到一个数组中,这就是为什么我们需要指定一个

我发现这种方法存在两个问题:

  • 此时我可能会删除原始 key 并仅使用索引,这是绝对不鼓励的。
  • 我的现实生活中的组件,向该组件提供项目的方式是通过子组件(我在这里过于简单化了以便理解这一点),因此我必须克隆每个元素才能更改键。

解决方案B

使用片段来分隔循环

   <Fragment key={0}>
     <div key='one'>foo</div>
     <div key='two'>bar</div>
   </Fragment>
   <Fragment key={1}>
     <div key='one'>foo</div>
     <div key='two'>bar</div>
   </Fragment>
   <Fragment key={2}>
     <div key='one'>foo</div>
     <div key='two'>bar</div>
   </Fragment>
   <Fragment key={3}>
     <div key='one'>foo</div>
   </Fragment>

这里感觉更干净,但同时这并不是首先添加片段的原因,所以也许它滥用了它们?

这个问题有更好的解决办法吗?社区标准是什么?

最佳答案

由于您使用的是Fragment,我假设您使用的是版本>16。在这种情况下,我认为还有另一种(也许更好)的方法来解决这个问题,即返回数组的数组。像这样的事情:

[
  [
    <div key='one'>foo</div>,
    <div key='two'>bar</div>,
  ],
  [
    <div key='one'>foo</div>,
    <div key='two'>bar</div>,
  ],
  [
    <div key='one'>foo</div>,
  ],
]

实际上,这与您的“解决方案 B”“等效”,但恕我直言,它不那么“hacky”,因为我认为 Fragment 不应该像那样使用。让我扩展一下:

在版本 16 之前,渲染函数无法返回 React 元素数组,这是非常烦人的事情。在版本 16 上,这开始成为可能,但是数组的元素必须始终有一个key,以便 React 的协调器正常工作,这意味着从渲染函数返回它是不好的:

[
  <span>foo</span>,
  <span>bar</span>,
] 

这是正确的:

[
  <span key="firstSpan">foo</span>,
  <span key="secondSpan">bar</span>,
] 

但是这样做有点奇怪和烦人。这就是 Fragment 被发明的原因,这样我们就可以返回这个:

<Fragment>
  <span>foo</span>
  <span>bar</span>
</Fragment>

因此,Fragment 的一大优点是我们不必为其子元素分配 key。这就是为什么我觉得看到带有“键控”子项的 Fragment 有点奇怪。

另外,我想说,我不认为你的“选项A”有什么问题。不过,我认为在大多数情况下,我提出的解决方案会更容易实现。

关于reactjs - React中重复元素的 key 管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54196477/

相关文章:

javascript - 如何从 ReactJS 中的 onClick 函数调用另一个组件

reactjs - 获取调度函数返回值

javascript - 使用react-redux获取另一个reducer的状态

reactjs - react /Redux : how to hold login fail

reactjs - 创建新的React应用程序后,在安装后导入软件包或将其包含在index.html中有什么区别?

javascript - 在reactjs中导出导入

javascript - 错误 : Request failed with status code 400. 在 POSTMAN 和应用程序中发送之间的差异

twitter-bootstrap - React 中表单输入字段的验证

javascript - 在 react 状态下用数组替换字符串时出错

reactjs - 来自服务器的数据时图例重叠