React-更新组件的三个阶段和源码解释

react源码分析:组件的创建和更新 本章从开始讲解了,初始化的时候,根节点的创建与更新流程,以及在类组件原型上挂载的一些更新的方法,但是为什么这一章不直接把他更新流程讲完呢?因为下一章要讲一下fiberNode这个东西,简而言之他只是一个架构概念,并不是React独有的,但是现在很有必要一起来看一看这个,那么下一章我们来一起揭开FiberNode的神秘面纱吧。 阅读详情

React 更新组件其实可以分为三个阶段:

  • Scheduler。任务优先级分配和调度
  • Render。更新组件内部状态,diff 计算 change
  • Commit。应用 change,执行副作用

Scheduler

该阶段主要是给任务分配优先级,统筹任务调度

Scheduler 的源码解析可以参考:https://juejin.cn/post/6889314677528985614

react 16 基于 requestIdleCallback 的 polyfill 方案来实现任务调度,用法如下:

window.requestIdleCallback(callback[, options])
let handle = window.requestIdleCallback((idleDeadline) => {
   
   
    const {
   
   didTimeout, timeRemaining} = idleDeadline;
    console.log(`是否超时?${
     
     didTimeout}`);
    console.log(`可用时间剩余${
     
     timeRemaining.call(idleDeadline)}ms`);
    // do sth
    const now = Date.now(), timespent = 10;
    while (Date.now() < now + timespent);
    console.log(`花了${
     
     timespent}ms`);
    console.log(`可用时间剩余${
     
     timeRemaining.call(idleDeadline)}ms`);
}, {
   
   timeout: 1000});
// 是否超时?false
// 可用时间剩余45ms
// 花了12ms
// 可用时间剩余32ms

由于 requestIdleCallback 有兼容问题,react 团队采用的是它的 polyfill 方案,可参考

  • https://www.zhuyuntao.cn/React%E4%B8%ADrequestIdleCallback%E7%9A%84polyfill%E5%AE%9E%E7%8E%B0
  • https://juejin.cn/post/6861590253434585096
react18
  • 更新时遍历更新每一个节点,每更新一个 Fiber 节点后,会判断累计更新时间是否超过 5ms。
  • 如果超过 5ms,将下一个更新创建为一个宏任务,浏览器自动为其分配执行时机,从而不阻塞用户事件等操作。
  • 如果更新的过程中,用户进行触发了点击事件,那么会在 5ms 与下一个 5ms 的间隙中去执行 click 事件回调

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Render

遍历 Fiber 树,得出需要更新的节点信息。可以被打断,让位于优先级更高的操作,比如用户点击等

  1. 从Fiber Root开始遍历,构建一个新的 Fiber 树。performSyncWorkOnRoot(root)–>renderRootSync
  2. 更新每个 fiber。workLoopSync–>performUnitOfWork–>beginWork
function workLoopSync() {
   
   
  // workInProgress:当前正在处理的节点
  while (workInProgress !== null) {
   
   
    performUnitOfWork(workInProgress);
  }
}

function performUnitOfWork(unitOfWork: Fiber): void {
   
   
  const current = unitOfWork.alternate;
  // ...
  // NOTE
  next = beginWork(current, unitOfWork, subtreeRenderLanes);
  // ...
  if (next === null) {
   
   
    // 如果没有子节点,则完成当前工作
    completeUnitOfWork(unitOfWork);
  } else {
   
   
    workInProgress = next;
  }
  ReactCurrentOwner.current = null;
}

beginWork 主要做了以下事情:

  1. 判断 fiber 节点是否可以复用
  2. 根据不同的 Tag(标记不同的组件类型:纯组件、函数组件、类组件),生成不同的 fiber 节点赋值给workInprogress.child
function beginWork(current, workInProgress, renderLanes) {
   
   
  // ...
  switch (workInProgress.tag) {
   
   
    // ...
    case FunctionComponent: {
   
   
      const Component = workInProgress.type;
      const unresolvedProps = workInProgress.pendingProps;
      const resolvedProps =
        workInProgress.elementType === Component
          ? unresolvedProps
          : resolveDefaultProps(Component, unresolvedProps);

      // NOTE
      return updateFunctionComponent(
        current,
        workInProgress,
        Component,
        resolvedProps,
        renderLanes,
      );
    }
    case ClassComponent: {
   
   
      const Component = workInProgress.type;
      const unresolvedProps = workInProgress
从源码来看React 的虚拟 DOM 和更新机制 函数是协调阶段的核心,它会根据不同类型的 Fiber 节点执行相应的更新逻辑,生成新的 Fiber 树。React 的并发模式允许中断和恢复渲染过程,这是通过时间切片(Time Slicing)实现的。React 使用 lanes 模型来表示优先级,不同的更新可以有不同的优先级。这种机制允许 React 在处理多个并发更新时,优先处理更重要的更新。// ... 其他类型的处理。// ... 其他类型的处理。// 阶段 2:Mutation。// 取消现有的调度(如果有)// 检查是否有待处理的工作。 阅读详情

相关推荐

【React】React18核心源码解读

【React】React18核心源码解读

owo_ovo的博客 2467

React 源码分析:深入虚拟 DOM 和 Diff 算法

虚拟 DOM (Virtual DOM) 是一个轻量级的 JavaScript 对象,它代表了真实 DOM 的结构。当 React 组件的状态发生变化时,React 会创建一个新的虚拟 DOM 树,并将其与旧的虚拟 DOM 树进行比较,找出需要更新的部分,然后只更新真实 DOM 中需要更新的部分。通过比较虚拟 DOM 树,可以找出需要更新的部分,避免不必要的 DOM 操作。虚拟 DOM 可以用于不同的平台,例如浏览器、Node.js、Native 应用等。

q68686的博客 1386

react源码解析8.render阶段

react源码解析8.render阶段 视频讲解(高效学习):进入学习 往期文章: 1.开篇介绍和面试题 2.react的设计理念 3.react源码架构 4.源码目录结构和调试 5.jsx&核心api 6.legacy和concurrent模式入口函数 7.Fiber架构 8.render阶段 9.diff算法 10.commit阶段 11.生命周期 12.状态更新流程 13.hooks源码 14.手写hooks 15.scheduler&Lane 16.concurrent模式 17.c

zz1999aa的博客 214

深入React源码揭开渲染更新流程的面纱

render会调用方法中,如果是第一次渲染,会先初始化FiberRoot,其为应用的起点。同时生成根节点的Fiber实例。这里Fiber;FiberRoot。调用会计算出此次更新的过期时间。并生成任务对象update,将其插入Fiber中的更新队列,然后调用触发任务调度会更新以该Fiber节点为根节点的整棵Fiber树的过期时间。然后调用进行调度中会绑定任务与具体执行函数。然后交由Scheduler处理。

It_kc的博客 752

React源码分析3-render阶段(穿插scheduler和reconciler)

当发生渲染或者更新操作时,react 去创建一系列的任务,任务带有优先级,然后构建 workInProgress fiber 树链表。遍历任务链表去执行任务。每一帧帧先执行浏览器的渲染等任务,如果当前帧还有空闲时间,则执行任务,直到当前帧的时间用完。如果当前帧已经没有空闲时间,就等到下一帧的空闲时间再去执行。如果当前帧没有空闲时间但是当前任务链表有任务到期了或者有立即执行任务,那么必须执行的时候就以丢失几帧的代价,执行这些任务。执行完的任务都会被从链表中删除。

It_kc的博客 578

【React】最新版本18 源码遨游(二) 组件 Component

React源码遨游(二) 组件 Component 文章目录React源码遨游(二) 组件 ComponentReact.Component`Component``ReactNoopUpdateQueue``setState``forceUpdate``ComponentDummy``PureComponent`总结 在React中,你可以将组件定义为class或者function 用class定义的组件会有更多的功能。定义一个组件类,你需要extend React.Component。 class Wel

ljinest 840

【React源码 - Fiber架构之Reconciler】

React源码-Fiber架构之Reconciler

weixin_44273311的博客 2124

React源码解读之任务调度

React设计体系如人类社会一般,拨动时间轮盘的那一刻,你便成了穿梭在轮片中的一粒细沙,角逐过程处处都需要亮出你的属性,你重要吗?你无可替代吗?你有特殊权限吗?没有,那不好意思,请继续在轮片中循环。属于你的生命之火殆尽,前来悼念之人很多,这幕,像极了出生时的场景。干啥玩意儿,这是技术文章不是抒情散文!下面进入正题。创建的准备上一节已经说明了,主要定义与更新相关的数据结构和变量,计算过期时间等。

weixin_59558923的博客 731

【前端面试】看react源码,解读useState

mount 阶段获取当前 Hook 节点,同时将当前 Hook 添加到 Hook 链表中初始化 Hook 的状态,即读取初始 state 值创建一个新的链表作为更新队列,用来存放更新操作setXxx(),赋值给Hook.queue创建一个 dispatch 方法(即 useState 返回的数组的第二个参数:setXxx()),该方法的用途是用来修改state,赋值给queue.dispatch返回当前 state 和 修改state 的方法(dispatch)

hhhh 1452

【React Hooks原理 - useReducer】

本文主要从基础使用入手,再进一步从源码来看useReducer实现原理两个方面来介绍useReducer这个Hook的基本原理和使用场景以及和useState的关系

weixin_44273311的博客 1442

【React Hooks - useState状态批量更新原理】

通过demo示例结合Chrome调试的方式从源码角度介绍了React17、React18对于状态批量处理的原理

weixin_44273311的博客 1795

万字长文+图文并茂+全面解析 React 源码 - render 篇

今天想了比较久的时间,准备开启这一系列的文章,旨在对 React 系列的源码进行深度解析,其中包含但不限于 react、react-dom、react-router... 等一系列优秀的 React 系列框架,最后再一一实现这些框架的简易版本。 本篇文章将会是对 react 和 react-dom 渲染过程源码的深度解析,我们将从官方 API 以及一些简易 Demo 来进入 react 的内部世界...

qq_34621851的博客 4122

前端成长之路(一)react中setState需要注意的几点及嵌套state的更新

一直没有对setState有什么很深入的了解,最近阅读了一些文章,深感setState的运用并不简单 setState的使用不当,很有可能会导致一些莫名其妙的bug 首先:setState并不保证同步执行 调用setState后,并不会直接改变state的值,而是会产生一个即将处理的state改变。在调用setState之后立即查看,有可能值并没有改变。所以,setState并没有办法保持同步,r...

Root的博客 2550

React进阶之React核心源码解析(一)

cline + deeseek => AI工具,上手成本非常低,非常便宜cursor 编辑器带着问题学源码学习方法论:由大到小 对比回答问题。

qq_34306228的博客 1233

QGIS三维地形可视化实战:从DEM数据到炫酷3D场景(附Qgis2threejs插件配置)

本文详细介绍了如何利用QGIS和Qgis2threejs插件,将DEM数据转化为交互式三维地形场景的完整工作流。核心内容包括DEM数据准备、坐标系选择(重点对比WGS 84与UTM的差异及影响)、插件核心参数配置、卫星影像与等高线叠加等进阶技巧,并提供了成果导出与常见问题解决方案,帮助用户高效创建可用于网页展示的炫酷3D可视化成果。

mqtt6iot的博客 877

【UE5+Quest3】手部模型替换---3-0

这次手部模型替换遇到了一些小问题,不过好在是bug一个个都处理掉了,我会分开几个章节去整理。详细的视频教程可以参考油管大佬的视频手部素材放到文章末尾,自行下载使用。(仅用作学习研究,不可用于商用)

qbbmnnnnnn的博客 946

esxi8.0.3如何添加USB外置硬盘

本文介绍了在ESXi系统中配置外置USB硬盘作为数据存储的完整步骤:1)通过SSH禁用USB仲裁服务并关闭自启;2)识别已连接的USB硬盘设备路径;3)使用partedUtil创建GPT分区表并计算扇区范围;4)设置VMFS6分区并格式化。关键命令包括停止usbarbitrator服务、partedUtil分区操作以及vmkfstools格式化命令。整个过程需通过SSH执行,最终将USB硬盘配置为名为"USB_Datastore"的VMFS6存储设备。

qq_41683719的博客 1547

夏令营纪实——东南大学计科院&PALM实验室面试全解析

本文详细解析了东南大学计科院与PALM实验室夏令营的面试全流程,包括前期准备、技术考察、项目经验深挖等关键环节。特别针对自然语言处理(NLP)和机器学习(ML)领域的高频问题提供应对策略,帮助申请者提升面试表现。文章还分享了实用的准备技巧和面试经验,为有意向参加该夏令营的学生提供宝贵参考。

convnet3designer的博客 459

想在 Visual Studio Code 里进行 ABAP 开发,需要安装的扩展列表

安装完毕后,我们可以将 SAP 系统配置为 Visual Studio Code 连接的远程文件系统。为了连接到 SAP 系统,需要启用 ABAP 开发工具 (ADT) ICF 节点,这与 SAP Hana Studio 等工具使用的服务相同。打开 SAP GUI 并连接到目标系统,运行事务 SICF,然后激活 ADT_SRV 服务,如下所示。这启用了允许代码编辑器和 IDE 连接到 SAP 系统的服务。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 3125

基于阿里云物联网平台设计的实时图传系统_采用MQTT协议传输图像

当前基于MQTT协议设计了一个实时图传系统,通过这个项目来演示,两个MQTT设备如何互相订阅,进行消息流转。 在阿里云服务器上创建2个设备,分为为设备A和设备B;设备A负责采集本地摄像头画面上传,设备B负责接收设备A上传的数据然后解析显示出来。在阿里云服务器上需要配置云产品流转,让设备A的数据上传后自动发送给设备B。这样就完成了视频画面数据的流转。不过因为阿里云的最大数据限制,每次最大发送10240字节的数据。

1万+

Vue3 - Element Plus 组件库 Tabs 标签页右侧区域插入按钮,<el-tabs> / <el-tab-pane> 选项卡组件右侧自定义插槽内容教程(右边区域添加自定义按钮功能区)

vue3,elementplus,tabs选项卡如何在插槽按钮,tabs标签页组件怎么自定义右侧内容,vue3elementplustabs组件右侧插槽按钮,element-plus在el-tabs组件的最右侧添加按钮,如何在选项卡右边加入按钮搜索框等内容,哪个属性能在tab选项卡右侧插入自定义按钮,在el-tabs组件最右侧添加按钮,vue3el-tabs组件怎么自定义右侧插槽内容,Tabs标签页右侧自定义插槽,ElementPlusTab右边加按钮,el-tabs组件自定义右侧按钮,在E

🏆 前端领域优质创作者 7018

面向RKNN平台的YOLOv11 Pose部署实战:模型转换、优化与端侧姿态估计推理

本文研究了YOLOv11 Pose模型在Rockchip RKNN平台上的部署方案。通过分析模型架构和关键技术,提出完整的转换流程,包括ONNX格式转换、检测头优化和量化配置。在RK3588硬件平台上实现了100 FPS的实时姿态检测,验证了该方案的可行性。研究主要贡献包括:1)提出YOLOv11 Pose到RKNN平台的完整转换方案;2)优化后处理算法;3)实现高效的边缘计算部署。实验结果表明,该方案能有效解决边缘设备计算资源受限的问题,为人机交互等应用场景提供了实用的技术方案。

m0_71589036的博客 613

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

上一篇: React-Fiber原理
下一篇: React-Hook原理
__lucas
博客等级 码龄9年 329粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值