React源码解析(1): JSX语法与react项目渲染过程

news/2025/1/13 18:06:13/文章来源:https://www.cnblogs.com/FatTiger4399/p/18664207

好家伙

 

0.前言

由于工作的需要,我不得不入手了react的全家桶,曾经我的主要技术栈是vue。

从vue转到react,一开始我感到非常不适应,jsx的语法的不了解,react hooks的使用方式,react路由的配置。。。这一度让我十分难受

但在熟悉一段时间后,我逐渐领略到react的魅力,灵活的状态管理,渲染速度,与vite集成后超快的打包速度,以及超漂亮UI组件库NextUI

 (这真是我目前为止遇到的最漂亮的一套组件库,圆角,配色,动画交互)

让我们拥抱新技术吧!

 

 

1. 关于 JSX

JSX 就是“JavaScript + XML”的神奇结合。它让我们能在写 JavaScript 的同时写出类似 XML 标签的东西,看起来就像是这样:

 

function App() {return (<NextUIProvider><RouterProvider router={router} /></NextUIProvider>);
}

 

实际上,这些标签最后会被编译成纯 JavaScript,也就是 React 官方的说法——JSX 会被转换成 React.createElement()。

去Babel的网站试一下吧

https://babeljs.io/repl

一个简单的表格
import React from "react";export function StudentTable() {const students = ["panghu", "xiaofu", "daxiong", "jinxiang"];return (<table style={{ borderCollapse: "collapse", width: "50%", margin: "1rem auto" }}><thead><tr style={{ backgroundColor: "#f2f2f2" }}><th style={{ border: "1px solid #ccc", padding: "8px" }}>序号</th><th style={{ border: "1px solid #ccc", padding: "8px" }}>姓名</th></tr></thead><tbody>{students.map((name, index) => (<tr key={index}><td style={{ border: "1px solid #ccc", padding: "8px" }}>{index + 1}</td><td style={{ border: "1px solid #ccc", padding: "8px" }}>{name}</td></tr>))}</tbody></table>);
}

 Babel编译后

 

但用 JSX 可读性更好,写着也舒爽。

 

2.为什么要用jsx?

我们来看vue和react实现相同表格

React

import React from "react";export function StudentTable() {const students = ["panghu", "xiaofu", "daxiong", "jinxiang"];return (<table style={{ borderCollapse: "collapse", width: "50%", margin: "1rem auto" }}><thead><tr style={{ backgroundColor: "#f2f2f2" }}><th style={{ border: "1px solid #ccc", padding: "8px" }}>序号</th><th style={{ border: "1px solid #ccc", padding: "8px" }}>姓名</th></tr></thead><tbody>{students.map((name, index) => (<tr key={index}><td style={{ border: "1px solid #ccc", padding: "8px" }}>{index + 1}</td><td style={{ border: "1px solid #ccc", padding: "8px" }}>{name}</td></tr>))}</tbody></table>);
}

 

Vue

<template><table style="border-collapse: collapse; width: 50%; margin: 1rem auto;"><thead><tr style="background-color: #f2f2f2;"><th style="border: 1px solid #ccc; padding: 8px;">序号</th><th style="border: 1px solid #ccc; padding: 8px;">姓名</th></tr></thead><tbody><trv-for="(student, index) in students":key="index"><td style="border: 1px solid #ccc; padding: 8px;">{{ index + 1 }}</td><td style="border: 1px solid #ccc; padding: 8px;">{{ student }}</td></tr></tbody></table>
</template><script>
export default {name: "StudentTable",data() {return {students: ["panghu", "xiaofu", "daxiong", "jinxiang"]};}
};
</script>

 

两段代码对比下来,你会发现

JSX语法虽然对UI进行了描述,但是,将“模板”和“逻辑”混合在一起了

 

在 JSX 中,你需要使用 JavaScript 的表达式(如变量、条件判断、循环等)直接对 UI 进行描述,类似于“模板 + 逻辑”的混合写法,具有较高的灵活度和可组合性。
 
刚开始时,我:jsx,真不行,一坨
两周后,我:这jsx哪里不行了,这jsx太棒了!
 
清晰的组件功能结构,以及动态生成UI无不让我觉得react写起来真是非常爽!

且在单文件内,就可以实现多组件,还不用考虑作用域,真是太爽了!

 

 

3.react项目渲染过程

3.1.ReactElement 的数据结构

虚拟 DOM 本质上是对真实 DOM 的抽象和映射,用一个轻量级的 JavaScript 对象来描述页面结构。
当需要更新 UI 时,框架会先在内存中(虚拟 DOM)进行计算与对比,然后再将差异高效地应用到真实 DOM。这样的理念可以减少不必要的真实 DOM 操作,进而提升性能。
 
在 React 中,“ReactElement”是构造虚拟 DOM 的核心数据结构,一般通过 JSX 或 React.createElement(...) 来创建。一个典型的 ReactElement 对象包含以下信息:
• type:要渲染的节点类型(字符串代表普通 DOM 标签,如 'div';或一个自定义组件)。
• props:节点的属性或子元素等相关数据。
• key、ref 等内部标识符(帮助 React 快速判断节点变化,或为组件提供引用)。
 
这些“ReactElement”对象构成了 React 的虚拟 DOM 树,框架会根据它们与旧的虚拟 DOM 树进行对比后,找出需要更新的节点并执行真实 DOM 操作。
Virtual DOM 更新对比流程
 
React 在进行更新时,使用一种称为“调和(Reconciliation)”的过程:
1) 首先创建新旧虚拟 DOM 树的对比;
2) 判断节点类型、key 等以定位可复用节点;
3) 如果节点类型相同,则会进一步比较子元素;若不同,则放弃复用,销毁旧节点并新建节点;
4) 计算出对真实 DOM 用户界面所需的最少量操作,然后执行更新。
通过这种方式,React 避免了很多没必要的真实 DOM 重绘,性能相对较高
 

3.2.渲染流程

流程:
1. 编写 JSX 代码:
 
  • 开发者使用 JSX 语法编写组件,这种语法类似于 HTML,但可以在 JavaScript 中使用。
  • Babel 编译:
  • Babel 是一个 JavaScript 编译器,它将 JSX 转换为 React.createElement 调用。这一步将 JSX 语法转化为 JavaScript 代码,使其可以在浏览器中运行。
 
3. React.createElement 调用:
  • React.createElement 是一个函数,用于创建 React 元素(ReactElement)。每个 JSX 标签都会被转换为一个 React.createElement 调用。
 
4. ReactElement 调用:
  • ReactElement 是一个轻量级的描述对象,表示界面上某个节点的结构和属性。它是构建虚拟 DOM 的基础。
 
5. 虚拟 DOM:
  • React 使用虚拟 DOM 来描述 UI 的结构。虚拟 DOM 是 ReactElement 的集合,表示应用的当前状态。
 
6. ReactDOM.render():
  • ReactDOM.render() 是 React 的核心方法之一。它的作用是将虚拟 DOM 渲染为真实 DOM。
  • 具体过程:
  • 接收虚拟 DOM 作为参数。
  • 比较新旧虚拟 DOM,找出差异。
  • 将差异应用到真实 DOM 上,更新界面。
  • 这个过程通过高效的差异算法(Diffing Algorithm)实现,确保只更新必要的部分,从而提高性能。
 
7. 真实 DOM:
 
  • 最终,经过 ReactDOM.render() 的处理,虚拟 DOM 的变化被应用到真实 DOM,用户界面得到更新。

 

 

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

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

相关文章

痞子衡嵌入式:我拿到了2024年度电子星球(eestar)最强大脑

今天收到了「电源网旗下电子星球」 颁发的 2024 年度最强大脑奖牌,这是电子星球第二年给痞子衡颁奖了。这个奖牌设计得非常用心,区别于去年奖牌只能捧在手上,今年痞子衡可以把奖牌挂脖子上出去拉风了。从23年8月开始,电子星球小编每个工作日会转发一篇痞子衡的技术原创文章…

使用嗅探大师(sniff master)进行手机端iOS抓包的配置步骤

一个强大的iOS端抓包工具,嗅探大师(sniff master),比市面上的一些抓包工具操作更简单。之前做网页端开发的时候找到一个抓包工具,嗅探大师,当时用来在Windows上面进行抓包,发现他在手机端iOS方面的抓包更为强大,而且还有HTTPS暴力抓包,无需设置代理,无需越狱,无需ro…

keycloak~巧用client-scope实现token字段和userinfo接口的授权

keycloak中的client-scope允许你为每个客户端分配scope,而scope就是授权范围,它直接影响了token中的内容,及userinfo端点可以获取到的用户信息,这块我们可以通过自定义scope/mapper,来实现粒度的控制,并且这个mapper可以控制添加到token,或者添加到userinfo端点,这两块…

.NET Core 委托原理解析

.NET Core 委托原理解析 在 .NET Core 中,委托(Delegate)是一种类型安全的函数指针,它允许你将方法作为参数传递给其他方法,或者将方法存储在变量中以便稍后调用。委托在事件处理、回调机制以及异步编程中非常有用。理解委托的运行原理对于掌握 .NET Core 的高级编程技巧至…

Ellyn-Golang调用级覆盖率&方法调用链插桩采集方案

在应用程序并行执行的情况下,精确获取单个用例、流量、单元测试走过的方法链(有向图)、出入参数、行覆盖等运行时数据,经过一定的加工之后,应用在覆盖率、影响面评估、流量观测、精准测试、流量回放、风险分析等研发效能相关场景。词语解释Ellyn要解决什么问题? 在应用程…

[megatron代码阅读] 1. 初始化和组网

以pretrain_gpt.py为例, 看megatron的整体逻辑. 本章主要包括megatron初始化相关逻辑, 核心函数为initialize_megatron, setup_model_and_optimizer两个 initialize_megatron parse_args 从argparse中直接读取超参数配置. 如学习率, 正则化等. 从环境变量中获取rank等 load_arg…

巧用VTable打造炫酷金字塔图表

在数据分析和可视化领域,表格是展示数据直观、有效的方式之一。今天,就让我们来探索如何利用VTable这个强大的表格组件,制作出既美观又富有信息量的金字塔图表,以及深入了解VTable中各种单元格类型的使用方法,让你的表格也能“绘”出精彩图表!在数据分析和可视化领域,表…

基于 Performace 分析事件循环

我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品。我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值。本文作者:千寻什么是事件循环? 我们为什么需要事件循环?对于 JavaScript 是一门单线程语言我们是肯定的,JavaScript 单线程的特性保证了渲…

万字图文:SaaS业务架构、价值流、业务能力、业务流程、业务对象、组织架构

大家好,我是汤师爷~ 本文为读者提供一个SaaS业务架构的系统性框架,探讨业务架构分析的核心要素,帮助SaaS企业深入剖析目标客户的业务模式,全面理解他们的业务架构。 无论你是SaaS创业者、产品经理还是架构师,本文内容都将为你的系统设计和决策提供帮助。 1 目标与步骤 Saa…

老奶奶看了都会的WSL2连接USB设备教程!

老奶奶看了都会的WSL2-Ubuntu连接USB设备教程!作者:SkyXZ CSDN:SkyXZ~-CSDN博客 博客园:SkyXZ - 博客园参考资料:微软官方文档连接 USB 设备 | Microsoft Learn在Win11上用WSL2安装Ubuntu来开发简直不要太爽!!!但是很多小伙伴会发现,欸~为什么我在宿主机上插入的USB设…

HighReport报表工具V4.0带来十大核心优势变化

1.概述经过一年时间产品升级研发,HighReport报表工具正式推出V4.0版本,报表算法和报表功能获得全面提升。HighReportV4.0带来全面质的飞跃,具有明显的产品优势。 2.亮点一:双父格扩展模型报表引擎核心算法是父子格扩展模型,下面是常见模型一般报表厂商下面的扩展模型是不支…

一个超经典 WinForm,WPF 卡死问题的终极反思

一:背景 1. 讲故事 写这篇文章起源于训练营里一位朋友最近在微信聊到他对这个问题使用了一种非常切实可行,简单粗暴的方式,并且也成功解决了公司里几个这样的卡死dump,如今在公司已是灵魂级人物,让我也尝到了什么叫反哺!对,这个东西叫 Harmony, github网址: https://gi…