04_DOM的diffing算法

news/2024/10/18 12:22:06/

OM的diffing算法

  • 一、验证 diffing 算法的存在
  • 二、经典面试题:
    • 1、React/Vue 中的key 有什么作用?(key 的内部原理是什么?)
    • 2、为什么遍历列表时,key 最好不要用 index?
      • 1.虚拟 DOM 中 key 的作用:
      • 2.用 index 作为 key 可能引发的问题
      • 3.开发中如何选择 key?:

一、验证 diffing 算法的存在

当 input 输入内容,在时间变动的每一秒 输入类的dom 都没有变动或者被更新,diffing 算法存在

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div id="test"></div><!-- 引入 react 核心库 --><script type="text/javascript" src="./v18.3.0/react.development.js"></script><!-- 引入 react-dom,用于支持 react 操作DOM --><scripttype="text/javascript"src="./v18.3.0/react-dom.development.js"></script><!-- 引入babel, 用于将 jsx 转为 js --><script type="text/javascript" src="./v18.3.0/babel.min.js"></script><!-- 引入 prop-types,用于对组件标签属性进行限制, 存在 PropTypes --><script type="text/javascript" src="./v18.3.0/prop-types.js"></script><!-- 此处一定要写babel --><script type="text/babel">javascript">class Time extends React.Component{state = {date: new Date()}componentDidMount(){setInterval(()=>{this.setState({date: new Date()})},1000)}render(){return (<div><h1>Hello</h1><input type='text' /><span>现在是{this.state.date.toTimeString()}<input type='text' /></span></div>)}}ReactDOM.render(<Time />,document.getElementById("test"))</script>
</body>
</html>

二、经典面试题:

1、React/Vue 中的key 有什么作用?(key 的内部原理是什么?)

2、为什么遍历列表时,key 最好不要用 index?

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div id="test"></div><!-- 引入 react 核心库 --><script type="text/javascript" src="./v18.3.0/react.development.js"></script><!-- 引入 react-dom,用于支持 react 操作DOM --><scripttype="text/javascript"src="./v18.3.0/react-dom.development.js"></script><!-- 引入babel, 用于将 jsx 转为 js --><script type="text/javascript" src="./v18.3.0/babel.min.js"></script><!-- 引入 prop-types,用于对组件标签属性进行限制, 存在 PropTypes --><script type="text/javascript" src="./v18.3.0/prop-types.js"></script><!-- 此处一定要写babel --><script type="text/babel">javascript">/**慢动作回放--- 使用 index 索引值做为 key初始数据:{id: 1, name:'小刘', age: 24}{id: 2, name:'小陈', age: 25}初始的虚拟DOM:<li key=0>小刘---24</li><li key=1>小陈---25</li>更新后的数据:{id: 3, name:'小王', age: 21}{id: 1, name:'小刘', age: 24}{id: 2, name:'小陈', age: 25}更新数据后的虚拟 DOM<li key=0>小王---21</li><li key=1>小刘---24</li><li key=2>小陈---25</li>--------------------------------------------------慢动作回放--- 使用 id 索引值做为 key初始数据:{id: 1, name:'小刘', age: 24}{id: 2, name:'小陈', age: 25}初始的虚拟DOM:<li key=1>小刘---24</li><li key=2>小陈---25</li>更新后的数据:{id: 3, name:'小王', age: 21}{id: 1, name:'小刘', age: 24}{id: 2, name:'小陈', age: 25}更新数据后的虚拟 DOM<li key=3>小王---21</li> 更新,只需要渲染这一个真实dom<li key=1>小刘---24</li> 复用<li key=2>小陈---25</li> 复用*/class Person extends React.Component{state = {persons:[{id: 1,name: '小刘',age: 24},{id: 2,name: '小陈',age: 25}]}componentDidMount(){setInterval(()=>{this.setState({date: new Date()})},1000)}add = ()=>{let {persons} = this.statelet p = {id: persons.length+1,name: "小王",age: 21}this.setState({persons: [p, ...persons]})}render(){return (<div><button onClick={this.add}>添加一个新人</button><h1>展示人员信息</h1><h3>使用 index 索引值作为key</h3><ul>{this.state.persons.map((el,inx)=>{return <li key={inx}>{el.name}---{el.age}<input type='text' /></li>})}</ul><h3>使用 id(数据的唯一标识) 索引值作为key</h3><ul>{this.state.persons.map((el)=>{return <li key={el.id}>{el.name}---{el.age}<input type='text' /></li>})}</ul></div>)}}ReactDOM.render(<Person />,document.getElementById("test"))</script>
</body>
</html>

1.虚拟 DOM 中 key 的作用:

1)简单的说: key 是虚拟DOM对象的标识,在更新显示时key起着极其重要的作用
2)详细的说:当状态中的数据发生改变时, react 会根据【新数据】生成【新的虚拟DOM】,随后React 进行【新虚拟DOM】与【旧虚拟DOM】的diff比较,比较规则如下:
a、旧虚拟DOM中找到了与新虚拟DOM相同的key:
(1)若虚拟DOM中内容没变,直接使用之前的真实DOM
(2)若虚拟DOM中内容变了,则生成新的真实,随后替换掉页面中之前的真实DOM
b、旧虚拟DOM中未找到与新虚拟DOM相同的key
根据数据创建新的真实DOM,随后渲染到页面

2.用 index 作为 key 可能引发的问题

1、若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实 DOM 更新===》界面效果没问题,但效率低

2、如果结构中还包含输入类的 DOM:
会产生错误 DOM 更新===》界面有问题

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

3.开发中如何选择 key?:

1、最好使用每条数据的唯一标识作为 key,比如 id、手机号、身份证号、学号等唯一值
2、如果确定只是简单的展示数据,用 indexx 也是可以的


http://www.ppmy.cn/news/1517986.html

相关文章

.NET Razor类库-热加载 就是运行时编译

1.新建3个项目 1.1 一个.NET Standard2.1项目 IX.Sdk.SvnCICD4NuGet 1.2 一个.NET Razor类库项目 IX.Sdk.SvnCICD4NuGet.RazorWeb 1.3 一个.NET6 Web项目 IX.Sdk.SvnCICD4NuGet.Web 这3个项目的引用关系 Web引用 Razor类库 和 .NET Standard2.1 Razor类库引用.NET Standard2.1…

java设计模式day01--(类之间的关系、软件设计原则、单例设计模式)

视频网址&#xff1a;s1.设计模式-课程介绍_哔哩哔哩_bilibili 1&#xff0c;设计模式概述 1.1 软件设计模式的产生背景 "设计模式"最初并不是出现在软件设计中&#xff0c;而是被用于建筑领域的设计中。 1977年美国著名建筑大师、加利福尼亚大学伯克利分校环境结构…

wildberries、ozon卖家必看:如何打造安全稳定测评养号环境系统

在wb、OZON平台上进行环境搭建及测评自养号时&#xff0c;需要关注多个要点以确保操作的有效性和合规性。以下是对wb、OZON环境搭建要点及测评自养号技巧的详细阐述&#xff1a; 1.环境搭建要点 模拟底层硬件参数&#xff1a; 搭建稳定的物理环境&#xff0c;模拟俄罗斯当地…

ubuntu 更新网卡丢失

查看网卡设备信息 sudo lshw -c Network设备 处于 description: Ethernet interface root-MoreFine-S500:/etc/netplan# sudo lshw -c Network*-networkdescription: Ethernet interfaceproduct: RTL8125 2.5GbE Controllervendor: Realtek Semiconductor Co., Ltd.physical …

OpenHarmony源码解析之电话子系统——通话流程

一、简介 OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;电话子系统为 OS 提供了基础的无线通信能力。 支持 TD-LTE/FDD-LTE/TD-SCDMA/WCDMA/EVDO/CDMA1X/GSM 等网络制式的通信模块&#xff0c;能够提供高速的无线数据传输、互联网接入等业务&#xf…

【OpenGL】xcode+glfw画三角形

环境搭建 1. 执行brew install glfw 2. 项目中Build Settings中header Search Paths中添加glfw的include路径 3. 项目中Build Phases中的Link Binary With Libraries中添加glfw的lib文件&#xff08;路径/opt/homebrew/Cellar/glfw/3.4/lib/libglfw.3.4.dylib&#xff09;及…

以“更好的”价值主张,五粮特曲打响双节动销

执笔 | 姜 姜 编辑 | 扬 灵 按照白酒消费惯例&#xff0c;随着中秋节与国庆节临近&#xff0c;9月、10月历来是白酒销售的旺季&#xff0c;白酒市场的竞争早已暗流涌动&#xff0c;酒企摩拳擦掌进入备战状态。 作为五粮液旗下战略品牌&#xff0c;肩负全国中高价位战略重任的五…

腾讯提出一种新的针对风格化角色和逼真服装动画的生成3D运动转移方法,生成效果逼真!

来自腾讯XR视觉实验室的研究团队提出了一种创新的3D运动转移方法&#xff0c;专门针对风格化角色和逼真服装动画的生成。该方法能够将源动作准确地映射到目标角色上&#xff0c;同时考虑了角色身体的刚性变形和服装的局部物理动态变形。 与现有技术相比&#xff0c;这技术不仅…