资讯专栏INFORMATION COLUMN

index作为key是反模式

hightopo / 509人阅读

摘要:原文我曾多次看到开发者在渲染列表的时候把列表项的作为它的。更好一个产品级别的方案应该是一个更健壮的方法,能够处理分散创建列表项。它能够快速生成短无序友好唯一的,代码像下面这样为每个列表项生成一个唯一的,并在渲染列表的时候使用它作为。

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

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

{todos.map((todo, 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) =>
  
)}

另外的实现方式是把编号递增移动到抽象方法中,使用一个全局的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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91634.html

相关文章

  • 架构思想之CAP原理

    摘要:关系数据库的模型拥有高一致性可用性很难进行分区原子性一个事务中所有操作都必须全部完成,要么全部不完成。 由于自己负责后端的设计已经有一段时间,对设计的一些思想和理论有一些理解,但最近被问到什么是CAP时,却一脸懵逼,下来后专门针对CAP架构思想进行了一些专题学习,在这里也将这个概念引入给大家,大家可以有意识地了解和学习这个思想理念,帮助自己在后续设计功能时有更好的参考。 分布式领域C...

    Shisui 评论0 收藏0
  • 架构思想之CAP原理

    摘要:关系数据库的模型拥有高一致性可用性很难进行分区原子性一个事务中所有操作都必须全部完成,要么全部不完成。 由于自己负责后端的设计已经有一段时间,对设计的一些思想和理论有一些理解,但最近被问到什么是CAP时,却一脸懵逼,下来后专门针对CAP架构思想进行了一些专题学习,在这里也将这个概念引入给大家,大家可以有意识地了解和学习这个思想理念,帮助自己在后续设计功能时有更好的参考。 分布式领域C...

    Dr_Noooo 评论0 收藏0
  • 简单基于spring的redis配置(单机和集群模式)

    摘要:优点是反序列化时不需要提供类型信息,但缺点是序列化后的结果非常庞大,是格式的倍左右,这样就会消耗服务器的大量内存。使用库将对象序列化为字符串。优点是速度快,序列化后的字符串短小精悍。 需要的jar包:spring版本:4.3.6.RELEASE,jedis版本:2.9.0,spring-data-redis:1.8.0.RELEASE;如果使用jackson序列化的话还额外需要:jac...

    Tychio 评论0 收藏0
  • 数组七十二变

    摘要:方法返回的数组元素是调用的数组的一个子集。当数组中至少有一个元素调用判定函数返回,它就返回返回一个布尔值,当有一个元素符合条件就返回,否则返回和这两个方法使用指定的函数将数组元素进行组合,生成单个值。 会改变原数组的方法: push() 在尾部添加一个或多个元素,并返回数组长度 let arr = [1, 2, 3] arr.push(a, b) // 5 console.log...

    alexnevsky 评论0 收藏0
  • JavaScript数据结构与算法-Sort-(leetcode原题)

    摘要:说明你可以假设数组中所有元素都是非负整数,且数值在位有符号整数范围内。提示按奇偶排序数组给定一个非负整数数组,中一半整数是奇数,一半整数是偶数。对数组进行排序,以便当为奇数时,也是奇数当为偶数时,也是偶数。 原博客地址:https://finget.github.io/2019... 排序 showImg(https://segmentfault.com/img/remote/146...

    Hanks10100 评论0 收藏0

发表评论

0条评论

hightopo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<