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 计算)

相关推荐
默默地离开5 分钟前
从0到1掌握React+TypeScript开发:前端工程化实践指南
前端·react.js·typescript
Spider_Man6 分钟前
手指一拉,世界焕新:移动端下拉刷新全攻略
前端·javascript·react.js
遂心_40 分钟前
TypeScript + React:事件处理与状态管理的类型安全实践指南
前端·react.js·typescript
sophie旭1 小时前
《深入浅出react》总结之10. 4 State 更新揭秘
react.js·源码阅读
张元清1 小时前
一个usePrevious引发的血案
javascript·react.js·面试
Cuzblind1 小时前
React Hooks入门
前端·react.js
胡gh1 小时前
新朋友:Typescript,TypeScript 在 React 业务开发中的最佳实践
react.js·面试·typescript
啃火龙果的兔子2 小时前
React 图标库发布到 npm 仓库
前端·react.js·npm
JiaLin_Denny2 小时前
如何在在NPM发布一个React组件
前端·react.js·npm·npm组件·npm发布·npm发布组件·npm如何发布组件
樱花开了几轉11 小时前
React中为甚么强调props的不可变性
前端·javascript·react.js