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

Update 与 UpdateQueue 对象

1 ) 概述

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

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

js 复制代码
// 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 )结构类型

js 复制代码
// 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代码中:

    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对象优先级最高

相关推荐
青锐CC13 分钟前
webman使用中间件验证指定的控制器及方法[青锐CC]
中间件·前端框架·php
还是大剑师兰特27 分钟前
D3的竞品有哪些,D3的优势,D3和echarts的对比
前端·javascript·echarts
王解28 分钟前
【深度解析】CSS工程化全攻略(1)
前端·css
一只小白菜~34 分钟前
web浏览器环境下使用window.open()打开PDF文件不是预览,而是下载文件?
前端·javascript·pdf·windowopen预览pdf
方才coding39 分钟前
1小时构建Vue3知识体系之vue的生命周期函数
前端·javascript·vue.js
阿征学IT43 分钟前
vue过滤器初步使用
前端·javascript·vue.js
王哲晓43 分钟前
第四十五章 Vue之Vuex模块化创建(module)
前端·javascript·vue.js
丶213643 分钟前
【WEB】深入理解 CORS(跨域资源共享):原理、配置与常见问题
前端·架构·web
发现你走远了44 分钟前
『VUE』25. 组件事件与v-model(详细图文注释)
前端·javascript·vue.js
Mr.咕咕1 小时前
Django 搭建数据管理web——商品管理
前端·python·django