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

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

JSX 的本质

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

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

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

React.createElement() 的语法

相当于 vue 的 h 函数

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

例如

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);

会被Babel 转译为

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

React.createElement() 会创建对象

// 注意:这是简化过的结构
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 计算)

目录
相关文章
|
前端开发 JavaScript 开发者
React 中还有哪些其他机制可以影响任务的执行顺序?
【10月更文挑战第27天】这些机制在不同的场景下相互配合,共同影响着React中任务的执行顺序,开发者需要深入理解这些机制,以便更好地控制和优化React应用的性能和行为。
|
前端开发 JavaScript
React学习之——条件渲染
【10月更文挑战第16天】React 中没有像Vue中v-if这种指令。React 中的条件渲染和 JavaScript 中的一样,使用 JavaScript 运算符 if 或者条件运算符去创建元素来表现当前的状态,然后让 React 根据它们来更新 UI。
|
移动开发 前端开发 JavaScript
React 表单与事件
10月更文挑战第10天
228 1
|
前端开发
React 中高阶组件的原理是什么?
React 中高阶组件的原理是什么?
268 57
|
监控 前端开发 UED
在 React 18 中利用并发渲染提高应用性能
【10月更文挑战第12天】利用并发渲染需要综合考虑应用的特点和需求,合理运用相关特性和策略,不断进行优化和调整,以达到最佳的性能提升效果。同时,要密切关注 React 的发展和更新,以便及时利用新的技术和方法来进一步优化应用性能。你还可以结合具体的项目实践来深入理解和掌握这些方法,让应用在 React 18 的并发渲染机制下发挥出更好的性能优势。
312 59
|
前端开发 JavaScript 开发者
React 事件处理机制详解
【10月更文挑战第23天】本文介绍了 React 的事件处理机制,包括事件绑定、事件对象、常见问题及解决方案。通过基础概念和代码示例,详细讲解了如何处理 `this` 绑定、性能优化、阻止默认行为和事件委托等问题,帮助开发者编写高效、可维护的 React 应用程序。
619 4
|
前端开发 JavaScript 算法
React的运行时关键环节和机制
【10月更文挑战第25天】React的运行时通过虚拟DOM、组件渲染、状态管理、事件系统以及协调与更新等机制的协同工作,为开发者提供了一种高效、灵活的方式来构建用户界面和处理交互逻辑。这些机制相互配合,使得React应用能够快速响应用户操作,同时保持良好的性能和可维护性。
|
JavaScript 前端开发 算法
前端优化之超大数组更新:深入分析Vue/React/Svelte的更新渲染策略
本文对比了 Vue、React 和 Svelte 在数组渲染方面的实现方式和优缺点,探讨了它们与直接操作 DOM 的差异及 Web Components 的实现方式。Vue 通过响应式系统自动管理数据变化,React 利用虚拟 DOM 和 `diffing` 算法优化更新,Svelte 通过编译时优化提升性能。文章还介绍了数组更新的优化策略,如使用 `key`、分片渲染、虚拟滚动等,帮助开发者在处理大型数组时提升性能。总结指出,选择合适的框架应根据项目复杂度和性能需求来决定。
751 2
|
5月前
|
缓存 前端开发 JavaScript
React Hooks深度解析与最佳实践:提升函数组件能力的终极指南
🌟蒋星熠Jaxonic,前端探索者。专注React Hooks深度实践,从原理到实战,分享状态管理、性能优化与自定义Hook精髓。助力开发者掌握函数组件的无限可能,共赴技术星辰大海!
React Hooks深度解析与最佳实践:提升函数组件能力的终极指南
|
10月前
|
缓存 前端开发 数据安全/隐私保护
如何使用组合组件和高阶组件实现复杂的 React 应用程序?
如何使用组合组件和高阶组件实现复杂的 React 应用程序?
356 68