最近在看一本名叫《深入浅出React和Redux》这一书,里面谈到了react的dom更新比对,记录一下。

假设有这么一个组件

<ul>
<ListItem text="first" />
<ListItem text="second" />
<ListItem text="third" />
</ul>

现在,我们在这个组件的前面插入一个新的组件<ListItem text='zero' />

<ul>
<ListItem text="zero" />
<ListItem text="first" />
<ListItem text="second" />
</ul>

思考,怎么更新dom是最优的,react是去怎么更新?

按照我们的思维,最优的更新dom就是去把新增一个ListItem组件,放在第一个。把之前的第一个组件<ListItem text="first" /> 以及第二个组件<ListItem text="second" />往后挪一位。这样的结果是最好的。

可是react不是这样更新的!

它先去比较第一个ListItem组件,发现组件上的textfirst变成了zero,需要更新。第二个组件text之前的second变成了first,也需要更新,最后新创建一个组件,把它的text设置为second。react就完成了它的更新。

当然, React 并不是没有意识到这个问题,所以 React 提供了方法来克服这种浪费,不过需要开发人员在写代码的时候提供一点小小的帮助,这就是 key 的作用。

key的用法

在 React 的眼里,确定每一个组件在组件序列中的唯一标识就是它的位置,所以

它也完全不懂哪些子组件实际上并没有改变,为了让 React 更加“聪明”,就需要开发者

提供一点帮助。

如果在代码中明确地告诉 React 每个组件的唯一标识,就可以帮助 React 在处理这个

问题时聪明很多,告诉 React 每个组件“身份证号”的途径就是 key 属性。

  • 把之前的代码加上key
<ul>
<ListItem key={1} text="first" />
<ListItem key={2} text="second" />
<ListItem key={3} text="third" />
</ul>

现在再去插入一个ListItem组件放在最前面,让它key为0

<ul>
<ListItem key={0} text="zero" />
<ListItem key={1} text="first" />
<ListItem key={2} text="second" />
</ul>

现在,react根据key值,知道了第二个第三个组件是之前的第一个第二个,所以react会创建一个ListItem组件放在第一位,对于原有的两个组件只用原有的props触发更新。这里就需要组件内部的shouldComponentUpdate的钩子函数进行判断来减少不必要的更新。

但是这个 key 值只是唯一还不足够,这个 key 值还需要是稳定不变的,试想,如果

key 值虽然能够在每个时刻都唯一,但是变来变去,那么就会误导 React 做出错误判断,

甚至导致错误的渲染结果。

<ul>
{
Arr.map((item,index)=>(<ListItem key={index} text={item.text} />))
}
</ul>

用数组下标作为 key ,看起来 key 值是唯一的,但是却不是稳定不变的,随着 Arr

数组值的不同,同样一个Listltem 实例在不同的更新过程中在数组中的下标完全可能不

同,把下标当做 key 就让 React 彻底乱套了。

需要注意,虽然 key 是一个 prop ,但是接受 key 的组件并不能读取到 key 的值,因为key ref React 保留的两个特殊 prop ,并没有预期让组件直接访问。

react为什么不用数组的下标来绑定key的更多相关文章

  1. C语言定义数组时使用枚举作为数组的下标 ——c99功能

    部分参考了https://blog.csdn.net/wq3028/article/details/76204690 同时在电脑上进行验证 //温度,电磁阀传感器序号,方便数组定位 typedef e ...

  2. js数组的用法以及数组根据下标(数值或字符)移除元素

    1.创建数组var array = new Array();var array = new Array(size);//指定数组的长度var array = new Array(item1,item2 ...

  3. angular,vue,react的基本语法—动态属性、事件绑定、ref,angular组件创建方式

    基本语法: 动态属性: vue: v-bind:attr="msg" :attr="msg" react: attr={msg} angular [attr]= ...

  4. react state为数组时插入值

    react state为数组时,如何插入值.在react里,一切皆是状态state,如果想通过改变state修改渲染效果,只能yongsetState.但是setState又是key:value格式, ...

  5. js数组的基本用法及数组根据下标(数值或字符)移除元素

    1.创建数组 var array = new Array(); var array = new Array(size);//指定数组的长度 var array = new Array(item1,it ...

  6. PHP 获取数组随意下标key的上一个prev和下一个next下标值

    PHP 获取数组随意下标key的上一个prev和下一个next下标值 <? php $xoops[1] = '小'; $xoops[2] = '孩'; $xoops[3] = '子'; $xoo ...

  7. Vue中 v-for 绑定key和不绑定key的区别

    首先,它们区别主要在于 虚拟DOM的复用,绑定key可以更好的复用,下面来详细讲一下 假如我们有一个数组 arr = [1,2,3,4],我们要在2后面插入一个值9: 如果绑定了key值,那么会是这样 ...

  8. Winform开发之ComboBox和ComboBoxEdit控件绑定key/value数据

    使用 ComboBox 控件绑定key/value值: 因为 ComboBox 是有 DataSource 属性的,所以它可以直接绑定数据源,如 DataTable.ListItem 等. 使用 Da ...

  9. Vue中v-for不绑定key会怎样

    Vue的v-for不绑定key,默认行为和绑定key="index"是差不多的,官方没有默认这种行为的情况下,会导致所有列表DOM重新渲染.key="index" ...

  10. forEach 循环数组 # for in 循环对象 key # for of 循环对象 value

    forEach 循环数组 # for in 循环对象 key # for of 循环对象 value

随机推荐

  1. ETSI GS MEC 013,UE 位置 API

    目录 文章目录 目录 版本 功能理解 Relation with OMA APIs Relation with OMA API for Zonal Presence Relation with OMA ...

  2. ansible功能实现

    模糊匹配远程主机文件并拉取到本地服务器 又熬夜加班了.花很长时间研究出来.如何实现模糊匹配到的远程文件批量拉取到本地的剧本.使用copy模块的*,shll模块的* ls|grep XX都没有实现,貌似 ...

  3. 生物医学顶刊论文(JBHI-2024):TransFOL:药物相互作用中复杂关系推理的逻辑查询模型

    (2024.5.17)JBHI-TransFOL:药物相互作用中复杂关系推理的逻辑查询模型 论文题目:TransFOL: A Logical Query Model for Complex Relat ...

  4. redis cluaster (redis分布式集群 redis分片集群)

    redis cluaster (redis分布式集群) 高可用: 在搭建集群时,会为每一个分片的主节点,对应一个从节点,实现slaveof的功能,同时当主节点down,实现类似于sentinel的自动 ...

  5. Qt添加资源文件

    参考视频:https://www.bilibili.com/video/BV1XW411x7NU?p=27 以添加图片为例进行说明: 1)点击工程名,选择"添加新文件": 2)选择 ...

  6. js浮点数类型

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...

  7. Nodejs概述 安装Nodejs os模块 path模块 url模块 querystring模块

    一.Nodejs概述 介绍 相关网址: https://nodejs.org/zh-cn/ http://nodejs.cn/ Node.js 是一个开源与跨平台的JavaScript 运行时环境.它 ...

  8. Vue TypeScript 实战:掌握静态类型编程

    title: Vue TypeScript 实战:掌握静态类型编程 date: 2024/6/10 updated: 2024/6/10 excerpt: 这篇文章介绍了如何在TypeScript环境 ...

  9. 安装sql 2012 时遇到“需要更新的以前的 Visual Studio 2010 实例。”规则失败。

    "需要更新的以前的 Visual Studio 2010 实例."规则失败.此计算机安装了需要 Service Pack 1 更新的 Visual Studio 2010,必须安装 ...

  10. Java8中LocalDateTime与时间戳timestamp的互相转换及ChronoUnit工具类

    Java8中LocalDateTime与时间戳timestamp的互相转换及ChronoUnit工具类import java.time.*;import java.time.format.DateTi ...