React进阶 - 13(说一说 React 中的虚拟 DOM)

本章内容

目录

    • 一、为什么需要"虚拟DOM"
    • [二、虚拟 DOM" 带来的希望](#二、虚拟 DOM“ 带来的希望)
    • [三、虚拟 DOM" 的优势(性能大幅度提升 & 跨端应用)](#三、虚拟 DOM“ 的优势(性能大幅度提升 & 跨端应用))

上一节我们讲了 statepropsrender函数的关系,本节内容开始了解 React中的"虚拟 DOM" 相关知识。

一、为什么需要"虚拟DOM"

  • 上篇文章,我们知道:当组件的 state或者 props变化时,render函数会重新知己,界面也重新被渲染。
  • 然而,我们要知道,页面的重新渲染这个过程是非常耗性能的。
  • 假设没有 React, 我们要实现数据变化界面也随着变化,通常可以这么做
text 复制代码
方式一:
1、定义一个 state 数据
2、定义一个 "JSX模版"
3、将"数据+JSX模版"结合,生成真实 DOM 来显示
4、当数据变化时
5、"数据+JSX模版"相结合,生成真实DOM,替换原始 DOM
6、如此往复循环 4、5步骤

方式二:(对方式一进行优化下,不直接替换旧的 DOM,只替换变化的数据节点)
1、定义一个 state 数据
2、定义一个 "JSX模版"
3、将"数据+JSX模版"结合,生成真实 DOM 来显示
4、当数据变化时
5、"数据+JSX模版"相结合,生成真实 DOM
6、新的 DOM 和旧 DOM比对,找到只变化的节点
7、用新 DOM 变化的节点替换旧 DOM 变化处的节点
8、如此往复循环 5、6、7步骤


方式二相对于方式一的步骤增加了,但是性能会有所提升(局部替换比整体替换消耗的性能更少),但是方式二的比较过程同样耗费了些性能,这样来看,性能也没提升多少

二、虚拟 DOM" 带来的希望

基于上述的痛点,React提出了"虚拟 DOM"的方案。也就是方式三:

  • 1、定义一个 state数据
js 复制代码
this.state = {
  content: 'hello'
}
  • 2、定义一个 JSX 模版
js 复制代码
render() {
 return (
  <div id="d1">
    <span>{content}</span>
  </div>
 )
}
  • 3、"数据+JSX模版"结合,React底层会调用 React.createElement()接口,将 JSX 模版变成一个原始的"虚拟DOM"(虚拟DOM 本质是一个数组形式的 JS对象,用它来描述"真实的DOM")
text 复制代码
虚拟 DOM 格式:[标签名,标签属性,标签的子节点]

注意如果标签子节点又是一个完整的 DOM,那么还是遵循 "[标签名,标签属性,标签的子节点]" 的格式

那将 2中的"JSX模版"转为"JS对象"的底层实现。运行后发现,我们可以通过 React.createElement()来实现 JSX的功能。唯一的缺点就是很复杂,所以这也是为什么 JSX存在的原因,它是一个更加简便好用的方式

js 复制代码
// 1、注释掉这里,改用下面的 React.createElement方式实现
// render() {
//  return (
//   <div id="d1">
//     <span>{content}</span>
//   </div>
//  )
// }

// 2、使用 React.createElement方式实现上面注释的功能
render() {
 // 我们将"JSX 模板"用 craeteElement 方法来改写,其接收 3 个参数依次是:元素的标签名、标签的属性、元素的children 子节点
 return React.createElement("div", {id: "d1", React.createElement("span", {}, "hello")})
}

上面生成的"虚拟DOM"为:["div", {id: "d1"}, ["span", {}, "hello"]]

  • 4、根据上面的"虚拟DOM"生成"真实DOM"
html 复制代码
 <div id="d1">
    <span>{content}</span>
  </div>
  • 5、当数据 state变化
js 复制代码
this.state = {
  content: 'hello world'
}
  • 6、重复 3步骤,生成新的"虚拟DOM": ["div", {id: "d1"}, ["span", {}, "hello world"]]

  • 7、比较"旧的虚拟DOM"和"新的虚拟DOM",找到 span中的内容是有变更的

  • 8、直接操作 DOM,改变 span里的内容

三、虚拟 DOM" 的优势(性能大幅度提升 & 跨端应用)

  • "虚拟DOM"本质上是用 JS生成的一个 JS对象,这个转变消耗的性能较少。如果直接使用 JS生成一个 DOM元素,那么它是会底层调用 Web ApplicationAPI,性能消耗极大

  • 然后两个"虚拟DOM"之间比对,本质是 js对象的比对,其底层使用的"Diff算法"是不怎么消耗性能的。如果直接把两个"真实 DOM"进行比对,其性能消耗极大

  • "JS 对象"不仅可以让"浏览器"识别,在原生应用(Android IOS)上也可以(注意:"原生应用"里不存在 DOM的概念,所以真实的 DOM在原生应用中不被识别,无法使用),因此,有了"虚拟DOM"后,我们用它生成一些原生组件。

  • 这样的话,在复用"state"、"JSX模版"等代码优势下,让"虚拟DOM"在不同"端"中进行转化:网页端转化为"真实DOM",原生应用中转化为原生的"组件"

到此,本章内容结束!

相关推荐
hackeroink1 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者3 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-3 小时前
验证码机制
前端·后端
燃先生._.4 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖5 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235245 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240256 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar6 小时前
纯前端实现更新检测
开发语言·前端·javascript
寻找沙漠的人7 小时前
前端知识补充—CSS
前端·css