加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

index作为key是反模式

发布时间:2020-12-15 03:25:48 所属栏目:百科 来源:网络整理
导读:原文:Index as a key is an anti-pattern 我曾多次看到开发者在渲染列表的时候把列表项的index作为它的key。 {todos.map((todo,index) = Todo {...todo} key={index} /)} 这看起来很优雅,而且能够解决警告(这才是“真”问题,对吧?)的问题,这样做有什

原文:Index as a key is an anti-pattern

我曾多次看到开发者在渲染列表的时候把列表项的index作为它的key。

{todos.map((todo,index) =>
  <Todo {...todo}
    key={index} />
)}

这看起来很优雅,而且能够解决警告(这才是“真”问题,对吧?)的问题,这样做有什么危险呢?

It may break your application and display wrong data!

让我来解释,key是React唯一用来确定DOM元素的东西,如果你想列表增加一项或移除中间的某项,会发生什么事?如果key和之前一个一样React就会假定这个DOM元素和之前对应的组件是一个,但是它们可能并不是同一个了。

为了证明潜在的危险我创建了一个简单示例

这表明,如果不指定key的时候React会使用index,因为这是那个时候最好的猜测,而且它会警告你说这不是最优解(它通过令人困惑的语句表述这个意思)。如果你主动提供了它,React就认为你知道你在干什么。记住这个示例,它能产生不可预测的结果。

比较好

像这样的应该都有一个永久的唯一的属性,当列表项创建的时候它是最合适被设置为key的,显然我是在说id,我们可以用下面的方式使用它:

{todos.map((todo) =>
  <Todo {...todo}
    key={todo.id} />
)}

另外的实现方式是把编号递增移动到抽象方法中,使用一个全局的index来确保任何两个列表项的id不同。

todoCounter = 1;
function createNewTodo(text) {
  return {
    completed: false,id: todoCounter++,text
  }
}

更好

一个产品级别的方案应该是一个更健壮的方法,能够处理分散创建列表项。因此,我推荐使用shortid。它能够快速生成“短 无序 url友好 唯一”的id,代码像下面这样:

var shortid = require('shortid');
function createNewTodo(text) {
  return {
    completed: false,id: shortid.generate(),text
  }
}

TL;DR:为每个列表项生成一个唯一的id,并在渲染列表的时候使用它作为key。

参考和相关文章

  • Dynamic Children and Keyed Fragments in React Docs

  • Explanation from Paul O’Shannessy

  • The importance of component keys in React.js

  • React.js and Dynamic Children?—?Why the Keys are Important

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读