index做为key是反模式

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

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

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

这看起来很优雅,并且可以解决警告(这才是“真”问题,对吧?)的问题,这样作有什么危险呢?git

It may break your application and display wrong data!github

让我来解释,key是React惟一用来肯定DOM元素的东西,若是你想列表增长一项或移除中间的某项,会发生什么事?若是key和以前一个同样React就会假定这个DOM元素和以前对应的组件是一个,可是它们可能并非同一个了。npm

为了证实潜在的危险我建立了一个简单示例app

图片描述

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

比较好

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

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

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

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

更好

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

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

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

参考和相关文章

相关文章
相关标签/搜索