继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

使用Index 作为 key 是一种 anti-pattern(不被推荐的方法)

英明神武的牛
关注TA
已关注
手记 317
粉丝 30
获赞 175

很多时候,我看到开发人员在呈现列表时使用项目的index作为其key

{todos.map((todo, index) =>  )}

它看起来优雅,它确实摆脱了警告(这是'real'的问题,对吧?)。但是这么做有什么危险?

它可能会破坏你的应用程序并显示错误的数据

让我解释一下,key是React用来识别DOM元素的唯一东西。如果你将一个项目推入列表或删除中间的东西会发生什么?如果key与之前的相同,则React假定DOM元素表示与以前相同的组件,但这是不对的。

为了演示潜在的危险,我创建了一个简单的示例源码地址)。

事实证明,当没有任何东西传递时,React使用index作为key,因为这是目前最好的猜测。此外,它会警告你,它是不理想的(它说,有点混乱的话,是的)。如果你自己提供它,React只会认为你知道你在做什么 - 记住这个例子 - 可能会导致不可预知的结果。

更好

每个这样的项目应该有一个永久性 和 _独特_ 的属性。理想情况下,应在创建项目时分配它。当然,我正在谈论一个_id_。然后我们可以通过以下方式使用它:

{todos.map((todo) =>  )}

注意: 首先查看项目的现有属性。他们已经有可以用作_id_的东西了。.

一种方法是将抽象中的编号移动一步。使用全局索引确保任何两个项目都有不同的_id_s。

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

更好的解决方法

生产解决方案应该使用更强大的方法来处理物品的分布式创建。为此,我建议使用 shortid。它很快产生'hort non-sequential url-friendly unique'ID。代码可能如下所示:

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

TL;DR:为每个项目生成一个唯一的_id_,并在呈现列表时将其用作key

更新:来自规则的例外

许多人问他们是否总是需要生成ID。其他人建议使用index作为key的用例似乎是合理的。

确实,有时产生新的ID是多余的并且可以避免。例如翻译许可条款或贡献者名单。

为了帮助您做出决定,我将这三个例子的共同点放在一起:

  1. 列表和项目是静态的 - 它们不被计算并且不改变;

  2. 列表中的项目没有ID;

  3. 该列表从不重新排序或过滤。

以上条件 都满足时,你可以安全地使用索引作为关键。

#### 更新2:React,Preact和*React

虽然在这篇文章中我写了关于React的问题,但问题不是排它的。在像Preact这样的类似的库中,危险也存在。但是,效果可能会有所不同。

请参阅以下StackOverflow问题,其中最后一个元素消失。另请注意Preact创建者提供的答案中的解释t, Jason Miller.

参考文献和相关文章

译文出处

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP