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

本章内容

目录

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

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

一、为什么需要”虚拟DOM“

  • 上篇文章,我们知道:当组件的 state或者 props变化时,render函数会重新知己,界面也重新被渲染。
  • 然而,我们要知道,页面的重新渲染这个过程是非常耗性能的。
  • 假设没有 React, 我们要实现数据变化界面也随着变化,通常可以这么做
方式一:
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数据
this.state = {content: 'hello'
}
  • 2、定义一个 JSX 模版
render() {return (<div id="d1"><span>{content}</span></div>)
}
  • 3、”数据+JSX模版“结合,React底层会调用 React.createElement()接口,将 JSX 模版变成一个原始的”虚拟DOM“(虚拟DOM 本质是一个数组形式的 JS对象,用它来描述”真实的DOM“)
虚拟 DOM 格式:[标签名,标签属性,标签的子节点]注意如果标签子节点又是一个完整的 DOM,那么还是遵循 ”[标签名,标签属性,标签的子节点]“ 的格式

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

// 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“
 <div id="d1"><span>{content}</span></div>
  • 5、当数据 state变化
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“,原生应用中转化为原生的”组件“

到此,本章内容结束!

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

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

相关文章

前后台分离跨域交互

后台处理跨域 安装插件 >: pip install django-cors-headers插件参考地址&#xff1a;https://github.com/ottoyiu/django-cors-headers/项目配置&#xff1a;dev.py # 注册app INSTALLED_APPS [...corsheaders, ]# 添加中间件 MIDDLEWARE [...corsheaders.middleware.…

EasyCVR视频智能监管系统方案设计与应用

随着科技的发展&#xff0c;视频监控平台在各个领域的应用越来越广泛。然而&#xff0c;当前的视频监控平台仍存在一些问题&#xff0c;如视频质量不高、监控范围有限、智能化程度不够等。这些问题不仅影响了监控效果&#xff0c;也制约了视频监控平台的发展。 为了解决这些问…

Spring 的存储和获取Bean

文章目录 获取 Spring 上下文对象的方式存储 Bean 对象的方式类注解配置扫描路径&#xff08;必须&#xff09;Controller&#xff08;控制器存储&#xff09;Service&#xff08;服务&#xff09;Repository&#xff08;持久层&#xff09;Component&#xff08;工具&#xff…

HCIA-Datacom实验指导手册:3.2 实验二:生成树基础实验

HCIA-Datacom实验指导手册:3.2 实验二:生成树基础实验 一、实验介绍:二、实验拓扑:三、实验目的:四、配置步骤:步骤 1 掌握启用和禁用 STP/RSTP 的方法步骤 2 掌握修改交换机 STP 模式的方法步骤 3 掌握修改桥优先级,控制根桥选举的方法步骤 4 掌握修改端口优先级,控制…

【代码分享】

通讯录2 #define _CRT_SECURE_NO_WARNINGS#include<stdio.h> #include<assert.h> #include<stdlib.h> #include<stdbool.h> #include<string.h>struct contacts {char name[20];int age;char gender[10];char phone[12];char address[40]; }; t…

​LeetCode解法汇总2859. 计算 K 置位下标对应元素的和

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 描述&#xff1a; 给你一个下…

C语言实战系列二:简单超市收银系统

从一个简单的超市收银系统&#xff0c;我们来练习一个系统如何设计&#xff0c;然后如何实现的思路。 在Ubuntu环境下使用C语言编写一个简单的超市收银系统。以下是一个基本的示例&#xff0c;涵盖了商品管理、购物车、交易处理等功能。 代码 #include <stdio.h> #inc…

css不规则的文本环绕

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>不规则的文本环绕</title><style>.b…

flyway使用配置参数和注意事项介绍

文章目录 业务场景参数介绍initSqlsbaselineOnMigratebaselineVersiontargetvalidateOnMigrate SQL注意事项 业务场景 对于生产环境&#xff0c;随着项目版本迭代&#xff0c;数据库结构也会变动。如果一个项目在多个地方实施部署&#xff0c;且版本不一致&#xff0c;就需要一…

触发器和存储过程的区别

目录 触发器&#xff08;Trigger&#xff09; 定义和用途&#xff1a; 执行方式&#xff1a; 作用范围&#xff1a; 参数传递&#xff1a; 示例&#xff1a; 存储过程&#xff08;Stored Procedure&#xff09; 定义和用途&#xff1a; 执行方式&#xff1a; 作用范围…

CSS之粘性定位

让我为大家介绍一下粘性定位吧&#xff01; 大家应该都了解过绝对定位&#xff0c;它是相对于父级定位 那么粘性定位相对于谁呢&#xff1f; 它相对于overflow:hidden; 如果没找到就会跟fixed固定定位一样&#xff0c;相对于视口 <!DOCTYPE html> <html lang"en…

rust 引用/mut 的所有权

在任意给定时间&#xff0c;要么 只能有一个可变引用&#xff0c;要么 只能有多个不可变引用。 不可变引用&#xff08;shared reference&#xff09;实现了Copy trait&#xff0c;不会发生所有权转移可变引用&#xff08;mutable reference&#xff09;未实现&#xff0c;会发…

C++ 利用容器适配器,仿函数实现栈,队列,优先级队列(堆),反向迭代器,deque的介绍与底层

C 利用容器适配器,仿函数实现栈,队列,优先级队列【堆】,反向迭代器,deque的介绍与底层 一.容器适配器的介绍二.利用容器适配器实现栈和队列1.stack2.queue 三.仿函数介绍1.什么是仿函数2.仿函数的使用3.函数指针的使用1.函数指针的用处2.利用函数指针完成回调3.利用仿函数完成回…

Compose | UI组件(二) | Text() 文本组件

文章目录 Text() 简介Text() 参数说明Text() 显示文字fontSize 文字大小textAlign 文字对齐方式style 文字样式fontFamily 文字字体AnnotatedString 多样式文字maxLines 设置文本单行显示SelectionContainer 选中文字 总结 Text() 简介 显示文字的组件 Text() 参数说明 Comp…

免 费 小程序商城搭建之b2b2c o2o 多商家入驻商城 直播带货商城 电子商务b2b2c o2o 多商家入驻商城 直播带货商城 电子商务

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

cg插画设计行业怎么样,如何学习插画设计

插画设计行业是一个充满创意和艺术性的行业&#xff0c;随着数字化时代的不断发展&#xff0c;cg插画的应用范围越来越广泛&#xff0c;市场需求也在逐年增长。以下是一些关于acg插画设计行业的现状和发展趋势&#xff1a; 市场需求不断增长&#xff1a;随着广告、媒体、影视、…

HCIA学习作业二

要求&#xff1a;基于192.168.1.0/24进行合理划分&#xff0c;要求全网通 [AR3]display ip interface brief [AR3]display ip routing-table [AR1]display ip interface brief [AR1]display ip routing-table [AR2]display ip interface brief [AR2]display ip routing-tab…

Element-plus修改样式

场景 通过样式穿透修改前端element组件样式。 实现 1.button按钮 ::v-deep .el-button { border-radius: 0; border: 0; background-color: rgba(0, 194, 255) !important; color: black; } 2.form表单 ::v-deep .el-form { text-align: left; .el-form-item { text-align: lef…

Hadoop3.x源码解析

文章目录 一、RPC通信原理解析1、概要2、代码demo 二、NameNode启动源码解析1、概述2、启动9870端口服务3、加载镜像文件和编辑日志4、初始化NN的RPC服务端5、NN启动资源检查6、NN对心跳超时判断7、安全模式 三、DataNode启动源码解析1、概述2、初始化DataXceiverServer3、初始…

C# 在矩形内获取一个指定大小的矩形(两个矩形的中心点是重合的)

C# 在矩形内获取一个指定大小的矩形&#xff08;两个矩形的中心点是重合的&#xff09; 示例1&#xff1a; using System.Drawing;public class RectangleUtils {public static Rectangle GetInnerRectangle(Rectangle outerRectangle, Size innerSize){// 计算内部矩形的左上…