最近在看一本名叫《深入浅出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. postgresql 开启审计日志

    1.审计清单说明 logging_collector     --是否开启日志收集开关,默认off,推荐on log_destination       --日志记录类型,默认是stderr,只记录错 ...

  2. 使用自定义lua解析管理器调用lua脚本中的table

    [5] 使用自定义lua解析管理器调用table 访问数组类型的table CallLuaEntrance测试脚本中内容: //------------------------------------ ...

  3. [BZOJ4358]permu线段树+莫队

    先放代码 晚上补(争取) [BZOJ4358]permu 线段树+莫队做法 序列操作,多次询问,无修,标准的莫队. 在如何在不同区间内转移的问题上,我选择用线段树来维护(没听xfg讲回滚莫队不行啊) ...

  4. PyQt5自定义信号

    一.简介 在 PyQt5 中,自定义信号是一个常见的任务,通常用于在对象之间传递信息或触发特定行为.自定义信号需要继承自 QtCore.pyqtSignal 并定义其参数类型. 二.操作步骤 1.导入 ...

  5. 添加身份认证和鉴权方案-使用jwtbearer

    HTTP身份认证框架 RFC 7235 定义了一个 HTTP 身份验证框架,服务器可以用来质询(challenge)客户端的请求,客户端则可以提供身份验证凭据. 服务端开启了身份认证后.如果客户端访问 ...

  6. 痞子衡嵌入式:从JLink V7.62开始优化了手动增加新MCU型号支持方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是JLink 7.62优化了手动增加新MCU型号支持方法. JLink 工具可以说是搞单片机开发的必备神器,JLink 包括一个硬件仿真器 ...

  7. containerd 源码分析:启动注册流程

    0. 前言 containerd 是一个行业标准的容器运行时,其强调简单性.健壮性和可移植性.本文将从 containerd 的代码结构入手,查看 containerd 的启动注册流程. 1. 启动注 ...

  8. AI实战 | 手把手带你打造校园生活助手

    大家好,我是努力的小雨.最近,我开始将我的经验逐渐分享到B站,希望能够帮助大家通过扣子助手真正解决一些问题.最近有粉丝提出了一个需求,为了满足大家的期待,我已经制作了视频,详细介绍了这个助手的搭建思路 ...

  9. Android Media Framework - 开篇

    前言 Android Media是一块非常庞大的内容,上到APP的书写,中到播放器的实现.封装格式的了解,下到编解码组件的封装.VPU API的了解,每块内容的学习都需要我们下很大的功夫.此外,我们还 ...

  10. Android OpenMAX(二)OMX Component实现基础

    Android OpenMAX IL提供的API位于 frameworks/native/headers/media_plugin/media/openmax ,目录下存放有预定义的类型.组件句柄定义 ...