react【框架原理详解】JSX 的本质、SyntheticEvent 合成事件机制、组件渲染过程、组件更新过程

JSX 的本质

JSX 代码本身并不是 HTML,也不是 Javascript,在渲染页面前,需先通过解析工具(如babel)解析之后才能在浏览器中运行。

babel官网可查看 JSX 解析后的效果

更早之前,Babel 会把 JSX 转译成一个 React.createElement() 函数调用,功能与现在的 jsxs 函数类似

React.createElement() 的语法

相当于 vue 的 h 函数

  • 第1个参数:标签名(字符串),或组件(变量)
  • 第2个参数:属性为key 的对象
  • 之后的参数是子元素,多个子元素,也可以用数组包裹放在第三个元素的位置
  • 返回 vnode

例如

js 复制代码
const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);

会被Babel 转译为

js 复制代码
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

React.createElement() 会创建对象

js 复制代码
// 注意:这是简化过的结构
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world!'
  }
};

这些对象被称为 "React 元素"。它们描述了你希望在屏幕上看到的内容。React 通过读取这些对象,然后使用它们来构建 DOM 并保持随时更新。

SyntheticEvent 合成事件机制

react 中的事件,不是原生事件(vue 中是原生事件),而是SyntheticEvent 合成事件。

为什么要用合成事件机制 ?

  • 更好的兼容性和跨平台(自定义封装的合成事件对象,更方便添加兼容性和跨平台的相关代码)
  • 统一挂载到 document 或 id 为root 的根节点 (从 react 17 开始是 root ),可以减少内存消耗,避免频繁解绑
  • 方便事件的统一管理(如事务机制)

为什么从 react 17 开始,要改为绑定到 root?

因为这样更利于多个 React 版本并存,例如微前端。

组件渲染过程

  • 通过 props ,state 初始化变量
  • 通过 render() 函数生成虚拟节点 vnode
  • 通过 patch(elem, vnode) 函数(不一定叫 patch,具体可能是其他名字,功能相同)渲染页面

组件更新过程

  • 通过 setState(newState) 修改响应式变量,生成 dirtyComponents (可能有子组件)
  • 通过 render() 函数生成虚拟节点 vnode
  • 通过 patch(elem, vnode) 函数(不一定叫 patch,具体可能是其他名字,功能相同)渲染页面

更新的 patch 分为两个阶段

  • reconciliation 阶段-执行 diff 算法,纯 JS 计算
  • commit 阶段-将 diff 结果渲染 DOM

之所以分为了两个阶段,是为了方便 fiber 优化性能

fiber 优化性能的原理

fiber 是 React 的内部运行机制

  • 将 reconciliation 阶段拆分成多个任务(commit 阶段无法拆分)
  • 当 DOM 需要渲染时暂停 reconciliation 中的任务,等无需进行 DOM 渲染时继续执行 reconciliation 中的任务

通过 window.requestIdleCallback 可获知 DOM 是否需要渲染,但 window.requestIdleCallback 有的浏览器不支持,所以在不支持window.requestIdleCallback 的浏览器上,无法使用 fiber 优化性能

哪些场景需要 fiber 优化性能 ?

因 JS 是单线程,且和 DOM 渲染共用一个线程,当组件足够复杂,组件更新时,计算和渲染的压力都很大,同时再有 DOM 操作需求(动画,鼠标拖拽等),就很容易出现页面卡顿(DOM 渲染等待 JS 计算)

相关推荐
zqx_75 小时前
随记 前端框架React的初步认识
前端·react.js·前端框架
TonyH20021 天前
webpack 4 的 30 个步骤构建 react 开发环境
前端·css·react.js·webpack·postcss·打包
掘金泥石流1 天前
React v19 的 React Complier 是如何优化 React 组件的,看 AI 是如何回答的
javascript·人工智能·react.js
lucifer3111 天前
深入解析 React 组件封装 —— 从业务需求到性能优化
前端·react.js
秃头女孩y1 天前
React基础-快速梳理
前端·react.js·前端框架
sophie旭1 天前
我要拿捏 react 系列二: React 架构设计
javascript·react.js·前端框架
BHDDGT2 天前
react-问卷星项目(5)
前端·javascript·react.js
liangshanbo12152 天前
将 Intersection Observer 与自定义 React Hook 结合使用
前端·react.js·前端框架
黄毛火烧雪下2 天前
React返回上一个页面,会重新挂载吗
前端·javascript·react.js