react反模式之index做为key

react反模式之index做为key

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

我已经看到过不少React开发人员在渲染一个列表时使用index做为它的keyreact

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

这样写看起来很优雅而且确实摆脱了react的警告信息,那么这样写有危险的地方吗?


  这样会破坏你的应用让其显示出错误的数据 git

下面我来解释下,key是React来识别DOM元素的惟一属性。若是你往数组里面增长一些元素或者从数组中间移除一些东西会发生些什么呢?若是key属性和之前同样React会认为DOM元素表示的组件和之前是同样的,可是那是错误的。github

这里我有个简单的例子来演示这个潜在的危险源码
index错误例子npm

事实证实,React 会用index做为默认的key的值由于这个时候React认为用index是最合理的。所以,React会警告你那样作是为达标准的(这样说看起来有点困惑. 若是你本身提供了key属性React会认为你知道本身在作啥. 记住这个例子,它可能会致使错误。数组

Better

列表里面的每一项都应该又一个永久而且惟一的属性,理想状况下应该在建立列表的时候分配下去. 固然我指的是id. 咱们能够像下面这样使用它:ui

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

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

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

Much better

一个产品化的解决方案是它应该更加健壮,可以用来建立分散的列表项. 所以我强烈推荐一个npm包shortid, 它能够快速的生成一系列‘短的 无序的 对url友好的 惟一的’ id,下面是示例代码:spa

var shortid = require('shortid');

function createNewTodo(text) {
    return {
        completed: false,
        id: shortid.generate(),
        text
    }
}

TL;DR: 为每一个列表项生成一个惟一的id,而后在渲染列表项时做为key属性传给列表项.code

References and related articles

. Dynamic Childrenand 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

相关文章
相关标签/搜索