React18原理: React核心对象之Update、UpdateQueue、Hook、Task对象

05-React 状态更新 在 React 中触发更新的方式主要有以下几种:ReactDOM.render、setState、forUpdate 以及 hooks 中的 useState 等,关于 hooks 的后面会专门写一篇文章分析。 阅读详情

Update 与 UpdateQueue 对象


1 ) 概述

  • 在fiber对象中有一个属性 fiber.updateQueue
  • 是一个链式队列(即使用链表实现的队列存储结构)
  • 是和页面更新有关的

2 )Update对象相关的数据结构

// https://github.com/facebook/react/blob/v18.2.0/packages/react-reconciler/src/ReactFiberClassUpdateQueue.new.js#L123
export type Update<State> = {
  // eventTime: number, // 这个属性后续被删除了 可以忽略了
  lane: Lane,

  tag: 0 | 1 | 2 | 3,
  payload: any,
  callback: (() => mixed) | null,

  next: Update<State> | null,
};

export type SharedQueue<State> = {
  pending: Update<State> | null,
  lanes: Lanes,
  hiddenCallbacks: Array<() => mixed> | null,
};

export type UpdateQueue<State> = {
  baseState: State,
  firstBaseUpdate: Update<State> | null,
  lastBaseUpdate: Update<State> | null,
  shared: SharedQueue<State>,
  callbacks: Array<() => mixed> | null,
};
  • Update 属性
    • lane: update所属优先级
    • tag: 表示 update种,4种. UpdateState, ReplaceState, ForceUpdate, CaptureUpdate
    • payload: 载荷,update对象真正需要更新的数据,可以设置成一个回调函数或者对象.
    • callback: 回调函数.commit完成之后会调用.
    • next: 指向链表中的下一个,由于UpdateQueue是一个环形链表,最后一个update.next指向第一个update对象
  • UpdateQueue 属性
    • baseState: 表示此队列的基础state
    • firstBaseUpdate: 指向基础队列的队首
    • lastBaseUpdate: 指向基础队列的队尾
    • shared: 共享队列
    • callbacks: 用于保存有callback回调函数的update对象,在commit之后,会依次调用这里的回调函数.
  • SharedQueue 属性
    • pending:指向即将输入的update队列.在class组件中调用setState()之后,会将新的update对象添加到这个队列中来

updateQueue是fiber对象的一个属性,它们之间数据结构和引用关系如下

Hooks 对象


1 ) 概述

  • Hook用于 function 组件中,能够保持function组件的状态
  • 与class组件中的 state在性质上是相同的,都是为了保持组件的状态
  • 在rect@16.8以后,官方开始推荐使用Hook语法,常用的api有usestate, useEffect,usecallback等
  • 到目前为止,官方一共定义了17种Hook类型

2 )结构类型

// https://github.com/facebook/react/blob/v18.2.0/packages/react-reconciler/src/ReactFiberHooks.new.js#L148
export type Hook = {|
  memoizedState: any,
  baseState: any,
  baseQueue: Update<any, any> | null,
  queue: any,
  next: Hook | null,
|};

// /packages/react-reconciler/src/ReactFiberHooks.new.js#L126
export type Update<S, A> = {|
  lane: Lane,
  action: A,
  hasEagerState: boolean,
  eagerState: S | null,
  next: Update<S, A>,
|};

// /packages/react-reconciler/src/ReactFiberHooks.new.js#L134
export type UpdateQueue<S, A> = {|
  pending: Update<S, A> | null,
  lanes: Lanes,
  dispatch: (A => mixed) | null,
  lastRenderedReducer: ((S, A) => S) | null,
  lastRenderedState: S | null,
|};
  • Hook 属性

    • memoizedState: 内存状态,用于输出成最终的fiber树
    • basestate: 基础状态,当Hook.queue更过后,basestate也会更新.
    • baseQueue: 基础状态队列,在reconciler阶段会辅助状态合并.
    • queue: 指向一个Update队列
    • next: 指向该function组件的下一个Hook对象,使得多个Hook之间也构成了一个链表.
  • 注意

    • Hook.queue 和 Hook.baseQueue(即 UpdateQueue 和 Update)是为了保证 Hook 对象能够顺利更新
    • 与 fiber.updateQueue 中的 UpdateQueue 和 Update 是不一样的(且它们在不同的文件)
  • Hook与fiber的关系

    • 在fiber对象中有一个属性 fiber.memoizedState 指向fiber节点的内存状态.
    • 在function类型的组件中,fiber.memoizedState 就指向Hook队列(Hook队列保存了 function类型的组件状态).
    • 所以Hook也不能脱离fiber而存在,它们之间的引用关系如下:

Task 对象

  • scheduler包中,没有为task对象定义type,其定义是直接在js代码中:

    // https://github.com/facebook/react/blob/v18.2.0/packages/scheduler/src/forks/Scheduler.js#L345
    var newTask = {
      id: taskIdCounter++,
      callback,
      priorityLevel,
      startTime,
      expirationTime,
      sortIndex: -1,
    };
    
  • 属性解释:

    • id: 位移标识
    • callback: task最核心的字段,指向react-reconciler包所提供的回调函数.
    • prioritylevel: 优先级
    • startTime: 一个时间戳,代表task的开始时间(创建时间+延时时间).
    • expirationTime: 过期时间.
    • sortIndex: 控制task在队列中的次序,值越小的越靠前
  • 注意task中没有next属性,它不是一个链表,其顺序是通过堆排序来实现的

  • 小顶堆数组,始终保证数组中的第一个task对象优先级最高

react源码阅读3 update与updateQueue react-dom后续updateContainer部分。阅读React包的源码版本为16.8.6。   在上一章节中我们看到了react-dom中render函数的逻辑是给传入的React组件创建了一个fiberRoot对象,用于标识它是整个应用的起点,上面拥有很多应用更新相关的表示符。然后创建对应的fiber给fiberRoot节点,fiber对象是每一个ReactElement都拥有的节点,... 阅读详情

相关推荐

React中的高优先级任务插队机制

在React的concurrent模式下,低优先级任务执行过程中,一旦有更高优先级的任务进来,那么这个低优先级的任务会被取消,优先执行高优先级任务。等高优先级任务做完了,低优先级任务会被重新做一遍。 我们用一个具体的例子来理解一下高优先级任务插队。 有这样一个组件,state为0,进入页面,会调用setState将state加1,这个作为低优先级任务。React开始进行更新,在这个低优先级任务尚未完成时,模拟按钮点击,state加2,这个作为高优先级任务。可以看到,页面上的数字变化为0 -> 2

与其临渊羡鱼,不如退而结网 1425

React 的源码与原理解读(十):updateQueue 与 processUpdateQueue

这个章节是补充的章节,因为我突然发现将了 lanes 的时候提到了我们的 updateQueue ,我以前之前讲过了,结果发现之前因为涉及了大量 lanes 的内容所以没讲,那么在将 hooks 之前,我们补充一篇 updateQueue 以及相关操作的讲解,这篇会让你在我学习**lanes ** 系统之后,对于我们怎么样依赖 lanes 系统进行我们的更新有更深刻的了解

weixin_46463785的博客 2015

GD32F4系列Keil工程模板搭建全攻略(手把手教学版)

本文提供了一份详细的GD32F4系列Keil工程模板搭建指南。从软件安装、固件库获取、目录规划,到Keil工程创建、文件添加、关键配置(如编译器选项、头文件路径、时钟设置),再到代码定制与常见问题排查,手把手教你构建一个标准化、模块化的开发基础。文章重点介绍了如何利用官方固件库和代码模板,快速建立稳定高效的开发环境,适用于GD32F407等Cortex-M4内核芯片的入门与项目开发。

weixin_29159995的博客 429

react源码分析(12)-updateQueue介绍

目录 2021SC@SDUSC updateQueue总览--对前文中所提到的update做详细介绍 分析 processUpdateQueue函数 总结 2021SC@SDUSC updateQueue总览--对前文中所提到的update做详细介绍 首先说明一下在updateQueue中所提到的update类型所包含的具体结构。 export type Update<State> = {| // TODO: Temporary field. Will remove

weixin_45668912的博客 1133

总结-NuerIPS2023-Direct Preference Optimization:Your Language Model is Secretly a Reward Model

对比PPO,DPO的泛化能力更强。

m0_60361484的博客 1608

Qt界面编程(三)—— 父子关系、对象树、信号和槽(自定义信号和槽、Qt5与Qt4的写法)

Qt框架默认提供的标准信号和槽不足以完成我们日常应用开发的需求,比如说点击某个按钮让另一个按钮的文字改变,这时候标准信号和槽就没有提供这样的函数。但是Qt信号和槽机制提供了允许我们自己设计自己的信号和槽。声明在类的signals域下没有返回值,void类型的函数只有函数声明,没有定义可以有参数,可以重载通过emit关键字来触发信号,形式:emit object->sig(参数);

此心光明事上练的博客 1695

React16源码: React中的update和updateQueue的源码实现

在 `ReactDOM.render` 过程中,还需要创建一个 update 对象, `update` 用于记录组件状态的改变的一个对象,它存放于Fiber对象的 `updateQueue` 中,`updateQueue`,它是一个单向链表的结构,一次整体的更新过程当中, 可能在这个queue里会存在多 Update

Wang的专栏 1665

Altium Designer(AD)的简易使用

一、绘制原理图、原理图库 首先来说明原理图的概念。 根据百度百科,原理图,顾名思义就是表示电路板上各器件之间连接原理的图表。也就是表示芯片上的引脚连接什么元件,各个元件谁和谁相连,电源电压的大小之类的。​ 再来说一下原理图和原理图库的区别和联系。 原理图是某个产品的原理图设计文件;原理图库是设计原理图时用到的电子元件的电路符号的集合。绘制PCB板时先设计原理图即建立原理图文件,而在原理图文件中设计原理图前必须将原理图库文件加载到原理图编辑环境才能使用其中的电路符号。 接下来说明如...

qq_52630607的博客 2万+

14_React 中的更新队列 updateQueue

updateQueue 是挂在 Fiber / Hook 上的更新队列(链表),用于缓存 setState 产生的 update,并在 render 阶段按优先级(lane)依次计算出新的 state。setState这些方法使用相同的更新流程,因为它们都使用 updateQueue 这个数据结构。setState↓创建 update(带 lane)↓加入 updateQueue(环形链表)↓↓render 阶段:↓processUpdateQueue(计算 state)↓。

小秀的博客 284

华为灵衢UB总线介绍

华为发布"灵衢"(UB)超节点互联协议,旨在构建支持AI大模型计算的基础设施。该协议采用统一内存语义和对等架构,使设备可直接访问远程内存,实现资源池化。技术突破包括2.1微秒超低时延和TB级带宽,支持64节点、52万张昇腾卡的集群互联。相比传统RDMA,"灵衢"更注重系统级资源调度,而非单纯数据传输。华为开放技术规范,推动生态建设,已有厂商开发兼容IP核。"灵衢"可适应x86、RISC-V等架构,未来将扩展至百万卡规模集群。

技术引领业务创新 4429

N32在Keil中J-Link识别失败的排查与修复指南

本文详细解析了在Keil开发环境中,J-Link调试器无法识别N32系列MCU的常见问题。通过分步指导,从检查修改Keil工程配置文件、更新J-Link驱动,到手动添加N32专用设备支持包,系统性地提供了排查与修复方案,帮助开发者快速恢复调试连接,确保开发流程顺畅。

306

React18源码: task任务调度和时间分片

创建任务之后,最后请求调度 requestHostCallback(flushwork)(创建任务源码中的第5步)现在再次回到 react-reconciler包中,在调度过程中的关键路径中,还需要理解一些细节。1.在task注册完成之后,会设置fiberRoot对象上的属性,代表现在已经处于调度进行中。在 Renconciler 运行流程中总结的4个阶段中,注册调度任务属于第2个阶段。调度的目的是为了消费任务,接下来就具体分析任务队列是如何管理与实现的。这2大特性的实现,都集中于这个while循环。

Wang的专栏 1776

大数据数据埋点技术面试题及参考答案(持续更新)

事件:指的是用户执行的具体动作,如页面浏览、按钮点击、商品购买等。事件是触发数据记录的直接原因,是分析用户行为的关键点。属性:是与事件相关的额外信息,可以提供关于事件的更多上下文。例如,用户点击的按钮颜色、大小、页面位置等。属性有助于更细致地分析用户行为,理解事件发生的具体情境。事件和属性共同构成了数据埋点的数据模型,它们使得收集的数据具有可分析性,从而可以用于深入理解用户行为和优化产品。

大模型大数据攻城狮的专栏 2097

React-18:组件的生命周期

组件的生命周期初始化渲染和状态更新之后挂载完成组件将要卸载之前卸载组件组件的生命周期(旧)组件的生命周期(新)新旧生命周期的区别在哪里?新增 getDerivedStateFromProps新增getSnapshotBeforeUpdate生命周期例子 class Life extends React.Component { state = { opacity: 1 } render() { return ( <

臧小川的博客 4375

基于AI的智能开发环境—Trae在Web开发中的应用实战与性能评估【Trae项目实战】

Trae 是一款与 AI 深度集成的开发工具,提供智能问答、代码自动补全和基于 Agent 的 AI 自动编程能力,极大提升开发效率。它具备完备的 IDE 功能,如代码编写、项目管理和源代码管理等,同时还具备强大的 AI 助手,能够提供智能问答、实时代码建议、代码片段生成等服务。开发者可以通过自然语言与 AI 协作,从 0 到 1 开发项目,AI 会根据需求自动生成代码或创建文件。

一键难忘的博客 3万+

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

react源码分析(13)-updateQueue介绍(2)以及Lane模型

目录 2021SC@SDUSC 介绍getStateFromUpdate 谈谈update任务在react中的调用处理 Lane模型简介 谈谈react源码中的位运算 总结 2021SC@SDUSC 介绍getStateFromUpdate 在getStateFromUpdate函数中,通过更新任务将State进行更新。 function getStateFromUpdate<State>( workInProgress: Fiber, queue:..

weixin_45668912的博客 3061

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

深入React的生命周期(下):更新(Update)

前言本文是对开源图书React In-depth: An exploration of UI development的归纳和增强。同时也融入了自己在开发中的一些心得。 你或许会问,阅读完这篇文章之后,对工作中开发React相关的项目有帮助吗?实话实说帮助不会太大。这篇文章不会教你使用一项新技术,不会帮助你提高编程技巧,而是完善你的React知识体系,例如区分某些概念,明白一些最佳实践是怎么来的等等...

weixin_34082177的博客 873

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【React】React 性能优化

在最后插入数据有无key 意义不大。前面插入数据如果没有 key 后面的节点都需要修改,如果有key ,原节点只需要移动,不需要修改。React 在props 或者 state 发生改变时,会调用 React 的render 方法,创建一颗不同的树。:父组件渲染(父组件render 调用,所有子组件的render 都会重新调用)、(SCU) 生命周期,进行强制渲染。React 18 的更新流程基于。、Context 变化等。

小秀的博客 1694

react18中的函数组件底层渲染原理分析

插槽的作用,就是将父组件中的内容,原封不动的传递给子组件。想办法让组件更加灵活,具有更强的复用性。总结: 被冻结的对象,既是不可扩展的,也是密封的。被密封的,也是不可扩展的。元素,是数组的情况下,要使用下面的方式来接收,也可以使用。属性时,需要先拷贝一份,然后才能修改。插槽内容可以根据不同的需求,放到不同的位置。children 属性,传递子组件的。所以,我们在组件内部修改。html 片段用插槽。里面的方法来进行处理。

峰会路转的博客 740

【React】React学习:从初级到高级(三)

随着应用不断变大,应该更有意识的去关注应用状态如何组织,以及数据如何在组件之间流动。冗余或重复的状态往往是缺陷的根源。

分享自己学习过程获得的一些知识 814

React 源码讲解第 5 节- Update 对象和 UpdateQueue 对象

根据第三节和第四节的内容,创建了 RootFiber 对象和 FiberRoot 对象之后,接下来就是处理更新。

杏子 1099

react update的使用场景

所以此时a组件中 就需要用到update的方法 及时更新props的num的值。比如一个b页面中使用了外部组件a 此时num值为1111。当页面b下拉刷新时num值发生了变化变成了2222。此时应用到组件a的页面b才能去更新渲染以及逻辑的。

weixin_46451295的博客 210

【React源码】(十三) Hook 原理(概览)

本节首先引入了官方文档上对于Hook的解释, 了解Hook的由来, 以及Hook相较于class的优势. 然后从fiber视角分析了fiber与hook的内在关系, 通过函数, 把Hook链表挂载到了之上. 利用fiber树内部的双缓冲技术, 实现了Hook从current到转移, 进而实现了Hook状态的持久化.

weixin_44828588的博客 1483

React-forceUpdate()

默认情况下,当组件的state或props改变时,组件将重新渲染。如果你的render()方法依赖于一些其他的数据,你可以告诉React组件需要通过调用forceUpdate()重新渲染。 调用forceUpdate()会导致组件跳过shouldComponentUpdate(),直接调用render()。这将触发组件的正常生命周期方法,包括每个子组件的shouldComponentU...

Leon的博客 4万+

react 18新特性 了解一下

新版本react18 坐了哪些更改

lucky569的博客 2402

React18 生命周期

文章目录生命周期顺序Mounting 挂载顺序Updation 更新顺序Unmounting 卸载注意生命周期1. constuctor2. componentWillMount(废弃)3. static getDerivedStateFromProps(新增)4. render5. componentDidMount版本迁移 在17版本中 废除的生命周期有:componentWillMount,componentwillReceiveProps,componentWillUpdate 新增的生命周期

猫老板的豆 2032
上一篇: Nestjs框架: 多环境参数配置
下一篇: React18源码: reconciler执行流程
Wang's Blog
博客等级 码龄12年 7436粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值