react为什么不用数组的下标来绑定key
最近在看一本名叫《深入浅出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
组件,发现组件上的text
值first
变成了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的更多相关文章
- C语言定义数组时使用枚举作为数组的下标 ——c99功能
部分参考了https://blog.csdn.net/wq3028/article/details/76204690 同时在电脑上进行验证 //温度,电磁阀传感器序号,方便数组定位 typedef e ...
- js数组的用法以及数组根据下标(数值或字符)移除元素
1.创建数组var array = new Array();var array = new Array(size);//指定数组的长度var array = new Array(item1,item2 ...
- angular,vue,react的基本语法—动态属性、事件绑定、ref,angular组件创建方式
基本语法: 动态属性: vue: v-bind:attr="msg" :attr="msg" react: attr={msg} angular [attr]= ...
- react state为数组时插入值
react state为数组时,如何插入值.在react里,一切皆是状态state,如果想通过改变state修改渲染效果,只能yongsetState.但是setState又是key:value格式, ...
- js数组的基本用法及数组根据下标(数值或字符)移除元素
1.创建数组 var array = new Array(); var array = new Array(size);//指定数组的长度 var array = new Array(item1,it ...
- PHP 获取数组随意下标key的上一个prev和下一个next下标值
PHP 获取数组随意下标key的上一个prev和下一个next下标值 <? php $xoops[1] = '小'; $xoops[2] = '孩'; $xoops[3] = '子'; $xoo ...
- Vue中 v-for 绑定key和不绑定key的区别
首先,它们区别主要在于 虚拟DOM的复用,绑定key可以更好的复用,下面来详细讲一下 假如我们有一个数组 arr = [1,2,3,4],我们要在2后面插入一个值9: 如果绑定了key值,那么会是这样 ...
- Winform开发之ComboBox和ComboBoxEdit控件绑定key/value数据
使用 ComboBox 控件绑定key/value值: 因为 ComboBox 是有 DataSource 属性的,所以它可以直接绑定数据源,如 DataTable.ListItem 等. 使用 Da ...
- Vue中v-for不绑定key会怎样
Vue的v-for不绑定key,默认行为和绑定key="index"是差不多的,官方没有默认这种行为的情况下,会导致所有列表DOM重新渲染.key="index" ...
- forEach 循环数组 # for in 循环对象 key # for of 循环对象 value
forEach 循环数组 # for in 循环对象 key # for of 循环对象 value
随机推荐
- StarCoder2-Instruct: 完全透明和可自我对齐的代码生成
指令微调 是一种技术,它能让大语言模型 (LLMs) 更好地理解和遵循人类的指令.但是,在编程任务中,大多数模型的微调都是基于人类编写的指令 (这需要很高的成本) 或者是由大型专有 LLMs 生成的指 ...
- JDK源码阅读-------自学笔记(十九)(容器概念初探和泛型概念)
简介 数组存在的优势和劣质 优势 数组是线性序列,从效率和类型检查的角度讲,数组是最好的 劣势 不灵活,数组的大小是预先定义好的,不会随意改变 引入容器 容器这个概念就是装东西的介质,可以理解为能装东 ...
- pageoffice 6 实现pdf加盖印章和签字功能
PageOffice支持两种电子印章方案,可实现对Word.Excel.PDF文档加盖PageOffice自带印章或ZoomSeal电子印章(全方位保护.防篡改.防伪造).Word和Excel的盖章功 ...
- PageOffice调用本地office实现多人在线同时编辑Word文档
说明:多人同时在线编辑文件大多数会出现文档相互覆盖的问题,后保存的文档会覆盖先保存的文档.pageoffice的这个功能可以用程序控制不同用户打开文件后,编辑Word文档中属于自己的区域,并且不会互相 ...
- 现代农业|AIRIOT智慧农业管理解决方案
智慧农业是现代化技术在农业领域的应用和成果,其中物联网技术在促生产.保产量和降本增效方面起到了至关重要的作用.运用传感技术和软件平台系统对农业生产进行智能化平台化管理,解决掉传统农业问题的诸多痛点 ...
- python openstacksdk
调用方法 参考地址 https://github.com/openstack/openstacksdk 注意事项 1.需要安装openstacksdk.我这里装的好像是1.5版本的.opentask接 ...
- 超详细!深入分析PPTP虚拟专用网搭建与抓包
PPTP虚拟专用网搭建与抓包分析实验 实验目的:掌握PPP协议VPN的搭建,通过分析pptp建立,理解chap连接建立的过程 实验过程: 环境搭建 Windows 11系统 VMware虚拟机.kal ...
- C#的奇技淫巧:利用WinRM来远程操控其他服务器上的进程
前言:有时候远程服务器的进程你想偷偷去围观一下有哪些,或者对一些比较调皮的进程进行封杀,或者对一些自己研发的服务进行远程手动启动或者重启等,又不想打开远程桌面,只想悄咪咪地执行,那也许下面的文章会 ...
- 如何判断7z压缩文件格式
如果压缩文件的后缀不是7z,那么如何如何判断文件格式呢?那就是通过文件头判断. 7z文件头前6位,固定是:377ABCAF271C,其中前两位37.7A分别是"7""z& ...
- Java交换map的key和value值
在Java中,我们都知道直接交换Map的key和value是不被允许的,因为Map的接口设计是基于key-value对的,其中key是唯一的,并且是不可变的(在HashMap等常见的实现中,虽然key ...