【10】基础知识:React - DOM的diffing算法

在这里插入图片描述

一、虚拟 DOM 中 key 的作用

react/vue 中的 key 有什么作用?key的内部原理是什么?

简单来说:

key 是虚拟 DOM 对象的标识,在更新显示时 key 起着极其重要的作用,提高渲染效率,防止渲染错误。

详细的说:

当状态中的数据发生变化时,React 会根据【新数据】生成【新的虚拟DOM】

随后 React 进行【新虚拟DOM】与【旧虚拟DOM】的 diff 比较,比较规则如下:

1、【旧虚拟DOM】中找到了与【新虚拟DOM】相同的 key:若虚拟 DOM 中内容没变,直接使用之前的真实 DOM若虚拟 DOM 中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实 DOM2、旧虚拟DOM中未找到与新虚拟DOM相同的key根据数据创建新的真实 DOM,随后渲染到到页面

“就地复用” 策略:

当数据项的顺序发生改变时,他不会移动页面上的 DOM 元素匹配数据项顺序的改变,而是简单的复用此处的元素如果绑定了 key 属性,就可对当前 DOM 元素进行唯一标识,在进行数据更新渲染时,会基于 key 的变化重新排列 DOM 元素的顺序

二、用 index 作为 key 可能会引发的问题

界面效果没问题, 但效率低:

若对数据进行,逆序添加、逆序删除等破坏顺序操作,会产生没有必要的真实 DOM 更新

慢动作回放----使用 index 索引值作为 key根据 diffing 算法规则,所有 DOM 元素都需要都需要重生成新的真实 DOM:
存在相同key 0 和 1,但虚拟 DOM内容改成了,需要生成新的真实 DOM;
新增key2,需要生成新的真实 DOM。初始数据:
{ id: 1, name: '小张', age: 18 },
{ id: 2, name: '小李', age: 19 }
初始的虚拟 DOM:
<li key=0>小张---18</li>
<li key=1>小李---19</li>更新后的数据:
{ id: 3, name: '小王', age: 20 },
{ id: 1, name: '小张', age: 18 },
{ id: 2, name: '小李', age: 19 }
更新数据后的虚拟 DOM:
<li key=0>小王---20</li>
<li key=1>小张---18</li>
<li key=2>小李---19</li>

界面有问题:

如果结构中还包含输入类的 DOM,会产生错误 DOM 更新

慢动作回放----使用 index 索引值作为 key (界面有问题)根据 diffing 算法规则,内部 input “就地复用”策略顺序会错乱初始数据:
{ id: 1, name: '小张', age: 18 },
{ id: 2, name: '小李', age: 19 }
初始的虚拟 DOM:
<li key=0>小张---18<input type="text"/></li>
<li key=1>小李---19<input type="text"/></li>更新后的数据:
{ id: 3, name: '小王', age: 20 },
{ id: 1, name: '小张', age: 18 },
{ id: 2, name: '小李', age: 19 }
更新数据后的虚拟 DOM:
<li key=0>小王---20<input type="text"/></li>
<li key=1>小张---18<input type="text"/></li>
<li key=2>小李---19<input type="text"/></li>

注意:

如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用 index 作为 key 是没有问题的。

三、开发中如何选择key?

1、最好使用每条数据的唯一标识作为 key , 比如 id、手机号、身份证号、学号等唯一值。

2、如果确定只是简单的展示数据,用 index 也是可以的。

四、示例

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>key的作用</title>
</head>
<body><div id="test"></div><!-- 引入react核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入react-dom --><script type="text/javascript" src="../js/react-dom.development.js"></script><!-- 引入babel --><script type="text/javascript" src="../js/babel.min.js"></script><script type="text/babel">		class Person extends React.Component {state = {persons: [{ id: 1, name: '小张', age: 18 },{ id: 2, name: '小李', age: 19 }]}add = () => {const { persons } = this.stateconst p = { id: persons.length + 1, name: '小王', age: 20 }this.setState({ persons: [p, ...persons] })}render() {return (<div><h2>展示人员信息</h2><button onClick={this.add}>添加一个小王</button><h3>使用index(索引值)作为key</h3><ul>{this.state.persons.map((personObj, index) => {return <li key={index}>{personObj.name}---{personObj.age}<input type="text" /></li>})}</ul><hr /><hr /><h3>使用id(数据的唯一标识)作为key</h3><ul>{this.state.persons.map((personObj) => {return <li key={personObj.id}>{personObj.name}---{personObj.age}<input type="text" /></li>})}</ul></div>)}}ReactDOM.render(<Person />, document.getElementById('test'))</script>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/162011.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何通过Photoshop将视频转换成GIF图片

一、应用场景 1、将视频转有趣动图发朋友圈 2、写CSDN无法上传视频&#xff0c;而可以用GIF动图替代 3、其他 二、实现步骤 1、打开Photoshop APP 2、点击文件——导入——视频帧到图层 3、选择视频文件 4、配置视频信息&#xff0c;按照图片提示配置完毕之后点击确定&…

入门小白拥有服务器的建议

学习网络知识 当我们拥有了一台服务器以后,需要提前准备学习一些网络、服务器、互联网方便的知识, 以备在后续学习工作中使用。 建议的网络知识学习清单: 1. 网络基础知识:包括网络拓扑结构、协议、IP地址、子网掩码、网关等基础概念。 2. 网络安全:包括网络攻击类型、防…

Spring中注入的使用

目录 一、什么是注入&#xff08;Injection&#xff09; 1.1 为什么要注入 二、注入的基本使用 三、Spring注入原理分析 一、什么是注入&#xff08;Injection&#xff09; 注入就是通过Spring的配置文件&#xff0c;为所创建对象的成员变量进行赋值 1.1 为什么要注入 书接上…

idea dubge 详细

目录 一、概述 二、debug操作分析 1、打断点 2、运行debug模式 3、重新执行debug 4、让程序执行到下一次断点后暂停 5、让断点处的代码再加一行代码 6、停止debug程序 7、显示所有断点 8、添加断点运行的条件 9、屏蔽所有断点 10、把光标移到当前程序运行位置 11、单步跳过 12、…

wps/word 之 word中的两个表格 如何合并成为一个表格(已解决)

第一步&#xff1a;新建两个表格&#xff1a; 如何实现上面的两个表格合并呢&#xff1f; 分别选定每个表格&#xff0c;然后鼠标右键---》表格属性 在表格属性中的 表格---》选择 无文字环绕。 第二个表格按照同样的方法 设置 无文字环绕。 然后将中的文本行删去即可以了。选…

提升品牌形象:利用OLED透明拼接屏进行品牌展示

在当今数字化时代&#xff0c;OLED透明拼接屏作为一项引人注目的新兴技术&#xff0c;正逐渐改变着各行各业的显示方式。 OLED透明拼接屏技术 OLED透明拼接屏采用有机发光二极管&#xff08;OLED&#xff09;技术&#xff0c;能够提供卓越的显示效果。 与传统的液晶显示屏相比…

喜报!迅镭激光荣膺“江苏省智能制造领军服务机构”!

近日&#xff0c;“2023江苏省智能制造领军服务机构”名单揭晓&#xff0c;迅镭激光凭借在智能制造领域的强劲实力和突出的行业影响力位列其中&#xff0c;摘得该项殊荣。 近年来&#xff0c;智能制造正在成为全球传统工业和制造业转型升级的主要方向&#xff0c;越来越多的企业…

C++中的智能指针

智能指针是在 C 14 C14 C14中新引入的&#xff0c;所以在编译的时候最好加入 " − s t d c 14 " "-stdc14" "−stdc14"的编译选项。智能指针一共有两种&#xff0c;分别是 u n i q u e _ p t r unique\_ptr unique_ptr和 s h a r e d _ p t…

试着写几个opencv的程序

一、认识opencv OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源计算机视觉库&#xff0c;旨在提供丰富的图像处理和计算机视觉功能&#xff0c;以帮助开发者构建视觉应用程序。OpenCV最初由英特尔开发&#xff0c;现在由社区维护和支持。它支持…

【UE4 反射系统】 UCLAS UFUNCTION UPROPERTY 宏简单解析 持续更新

目录 0 引言1 C如何实现反射机制1.1 使用代码生成工具实现反射机制 2 UE4的反射系统2.1 ****.generated.h头文件2.2 GENERATED_BODY()2.3 反射宏 UCLASS 等2.4 UHT和UBT 3 基本宏的使用3.1 UCLASS3.2 UFUNCTION3.3 UPROPERTY &#x1f64b;‍♂️ 作者&#xff1a;海码007&…

Axure RP医疗在线挂号问诊原型图医院APP原形模板

医疗在线挂号问诊Axure RP原型图医院APP原形模板&#xff0c;是一款原创的医疗类APP&#xff0c;设计尺寸采用iPhone13&#xff08;375*812px&#xff09;&#xff0c;原型图上加入了仿真手机壳&#xff0c;使得预览效果更加逼真。 本套原型图主要功能有医疗常识科普、医院挂号…

美创科技信创数据安全「利基者」!

近日&#xff0c;第一新声研究部正式发布《2023年中国信创网络安全产品竞争力象限》&#xff08;下称“象限报告“&#xff09;。 ◼︎ 象限报告综合考虑企业占有率、在技术/应用上的成熟度、在客户方面的交付完成度及口碑、产品在市场/营销/商业模式/行业拓展等战略上的领先性…

解决Drag and drop is not supported导致无法将物理机上的文件拖入Ubuntu

问题起因 因为需要拷贝一个文件从物理机到虚拟机&#xff0c;但是我又不想用有关ftp的程序或者协议&#xff0c;但是直接拖又报错Drag and drop is not supported&#xff0c;索性上网查询了一下解决方法&#xff0c;自己记录一下。 解决方法 安装下面两个程序 sudo apt in…

python小游戏:小球碰撞

创建带图形界面的游戏通常需要使用图形库。Python有很多图形库&#xff0c;其中比较流行的包括Pygame, PyOpenGL, Panda3D等。在这里&#xff0c;我将用Pygame作为示例来编写一个简单的游戏。 在运行下面的代码之前&#xff0c;请确保你已经安装了Pygame库。你可以使用以下命令…

工控机连接Profinet转Modbus RTU网关与水泵变频器Modbus通讯配置案例

Profinet转Modbus RTU网关是一个具有高性能的通信设备&#xff0c;它能够将工控机上的Profinet协议转换成水泵变频器可识别的Modbus RTU协议&#xff0c;实现二者之间的通信。通过这种方式&#xff0c;工控机可以直接控制水泵变频器的运行状态&#xff0c;改变其工作频率&#…

美格智能SLM927智能模组,轻松打造功能丰富的智能终端

近年来&#xff0c;智能终端加速渗入各行各业&#xff0c;使用场景不断拓展&#xff0c;视觉、听觉、语音、传感等交互能力融入智能终端产品之中&#xff0c;带来涵盖工作和生活各场景的智能化浪潮。 美格智能作为全球领先的无线通信模组及解决方案提供商&#xff0c;深入洞察…

Linux网络编程系列之UDP组播

Linux网络编程系列 &#xff08;够吃&#xff0c;管饱&#xff09; 1、Linux网络编程系列之网络编程基础 2、Linux网络编程系列之TCP协议编程 3、Linux网络编程系列之UDP协议编程 4、Linux网络编程系列之UDP广播 5、Linux网络编程系列之UDP组播 6、Linux网络编程系列之服务器编…

Linux网络-UDP/TCP协议详解

Linux网络-UDP/TCP协议详解 2023/10/17 14:32:49 Linux网络-UDP/TCP协议详解 零、前言一、UDP协议二、TCP协议 1、应答机制2、序号机制3、超时重传机制4、连接管理机制 三次握手四次挥手5、理解CLOSE_WAIT状态6、理解TIME_WAIT状态7、流量控制8、滑动窗口 丢包问题9、拥塞控制…

【Qt-19】按Q退出应用程序

如何将Qt窗口应用程序改成控制台程序呢&#xff1f; 下面进入正文&#xff0c;如何控制控制台程序退出呢&#xff1f; 这里采用线程方式&#xff0c;通过单独线程监视用户输入来执行是否退出程序。 监视线程头文件thread.h #include <QThread> #include "TDRServe…

【ARM裸机】ARM入门

1.ARM成长史 2.ARM的商业模式和生态系统 ARM只设计CPU&#xff0c;但是不生产CPU 3.为什么使用三星&#xff1a;S5PV210 4.各种版本号 0. ARM和Cortex Cortex就是ARM公司一个系列处理器的名称。比如英特尔旗下处理器有酷睿&#xff0c;奔腾&#xff0c;赛扬。ARM在最初的处理器…