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

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

时间:2025-01-13 18:10:28浏览次数:1  
标签:React DOM ReactElement react 虚拟 JSX 源码

好家伙

 

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>
      <tr
        v-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,用户界面得到更新。

 

 

标签:React,DOM,ReactElement,react,虚拟,JSX,源码
From: https://www.cnblogs.com/FatTiger4399/p/18664207

相关文章

  • java企业人事档案管理系统论文+源码 2025毕设
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景在当今企业快速发展的环境下,企业规模不断扩大,员工数量日益增多,人事管理工作变得愈发复杂。传统的人事档案管理方式主要依赖手工操作和纸质档案,这......
  • java面试刷题系统设计论文+源码 2025毕设
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景随着就业市场竞争的日益激烈,面试在求职过程中的重要性愈发凸显。如今,计算机技术的广泛应用为面试准备提供了新的途径。在传统的面试准备过程中,求......
  • 【最新原创毕设】基于SSM的在线学习平台+09650(免费领源码)可做计算机毕业设计JAVA、PHP
    目 录摘要1绪论1.1选题背景及意义1.2国内外现状分析1.3论文结构与章节安排2 在线学习平台系统分析2.1可行性分析2.2系统业务流程分析2.3系统功能分析2.3.1功能性分析2.3.2非功能性分析2.4系统用例分析2.5本章小结3在线学习平台总体设......
  • 源码分析之Openlayers中CanvasLineStringBuilder类
    访问Openlayers网站(https://jinuss.github.io/Openlayers_map_pages/,网站是基于Vue3+Openlayers,里面有大量的实践和案例。觉得还不错,可以给个小星星Star,鼓励一波https://github.com/Jinuss/OpenlayersMap哦~概述在Openlayers中,CanvasLineStringBuilder类用于构建......
  • 【附源码】springboot 高校教师工作量管理系统设计与实现
    博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数......
  • 【附源码】springboot 干洗店预约洗衣系统设计与实现
    博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数......
  • 【附源码】springboot 在线学习过程管理系统软件设计与实现
    博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数......
  • 【附源码】springboot Javaweb 的网上商城系统设计与实现
    博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数......
  • 【附源码】springboot 在线学习过程管理系统软件设计与实现
    博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数......
  • 【附源码】springboot 干洗店预约洗衣系统设计与实现
    博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数......