React Hook & 周边技术原理

ReactHook

ReactHook 思维导图

Fiber Node 结构

这里只关系与 hooks 实现有关的内容

属性名 类型 说明
tag Number 组件类型。如这个组件是类组件、函数式组件,或其它什么类型的组件。
type Function String Symbol Number Object FiberNode的类型。对于Component类的组件,type就是它的Class名。对于函数式组件来说,type就是这个FiberNode对应的函数本身。
memoizedState Object 当前 state。 具体的说,这是组件的第一个Hook (组件hook作为一个环形单向链表存在)
updateQueue Object 更新队列。记录了React组件更新的副作用,在EffectHook中会谈到。

Hook (memoizedState)

这指的是Fiber.memoizedState 的链表项内容

属性名 类型 说明
memoizedState any hook的当前值 (不同的hook有不同的结构)
queue UpdateQueue<any, any> null 当前hook的更新队列
next Hook null 这个hook后面的一个hook

为什么 hook 是一个环形链表 ?为了性能考虑,如果用数组,插入和删除复杂度高

如果使用单向链表,插入需要遍历到最后,使用环形链表比较好

Dispatcher

React 根据渲染阶段的不同,使用不同的 dispatcher ,执行其中的函数(hook)

  • 挂载 HooksDispatcherOnMount (通过当前hook是否为空判断) --> 绑定更新函数到 fiber 上
  • 更新 HooksDispatcherOnUpdate --> 读取旧状态,合并更新队列,计算新值触发更新
  • 一个在渲染过程中触发的再次更新: HooksDispatcherOnRerender
  • 用于错误处理的:(在非法位置调用hook)ContextOnlyDispatcher --> 抛出异常(在执行完渲染后再切换回这里)
javaScript 复制代码
const HooksDispatcherOnMount: Dispatcher = {
  useEffect: mountEffect,
  useMemo: mountMemo,
  useState: mountState,
  ...
};

const HooksDispatcherOnUpdate: Dispatcher = {
  useEffect: updateEffect,
  useMemo: updateMemo,
  useState: updateState,
  ...
};

流程

state

  1. 挂载

    1. 首次调用的时候,将 hook 数据挂载到 WIP Fiber 上 (memorizedState) 形成一个 单向链表

    2. 使用 HooksDispatcherOnMount ,此时 Hook 调用 mountXXX 方法,初始化状态,绑定更新函数

      1. 生成的 dispatch 除了通过 bind 绑定了当前上下文,还提前传入的 FiberNode 等参数
    3. 最终返回 [ state ,dispatch ]

  2. 更新 ( 调用 setState )

    1. 从当前 Current 树中获取旧 Fiber 的 hook 数据
    2. 通过 HooksDispatcherOnUpdate ,创建 action 推入 推入对应 hook 的 queue 上
    3. 触发调度 ,开始构建 WIP 树 : 通过 updateWorkInProgressHook 从 Current 中取出旧状态,计算并更新到新的 WIP 的 Hook 链表中
    4. 调度器根据优先级判断是否需要中断/重组任务队列

effect

  1. 挂载

    1. 首次调用的时候,HooksDispatcherOnMount 调用 mountEffect 方法,创建 Effect 对象

      1. 挂载到 WIP 树到 updateQueue 环形链表中 (创建的时候需要执行一次)
  2. 更新

    1. 在 beforeMutation 阶段,通过与当前 current 树上的 effect 的依赖的对比,判断是否需要执行 updateQueue 中的函数(打标)
    2. 最后在执行完更新,调度执行 updateQueue 。 保存 destory 函数(在Effect对象内)
  3. 卸载

    1. 卸载的时候需要执行 Effect 的所有 destory 函数

Effect List

Effect List 副作用链在 compeletWork 环节收集,收集的内容是 fiber 节点上的 Effect 副作用 和 DOM 操作函数。

EffectList 会在commit 阶段执行三次遍历

  1. Before Mutation 异步调度 effect (messageChannel 宏任务)
  2. Mutation 同步执行 DOM
  3. Layout 同步执行 layoutEffect (此时DOM还没有渲染,只是挂载,所以能够防止闪屏)

Redux 单项数据流

React-Router

笔者才疏学浅,各位读者多多担待,不吝赐教。

相关推荐
蓉妹妹1 小时前
React项目添加react-quill富文本编辑器,遇到的问题,比如hr标签丢失
前端·react.js·前端框架
vvilkim2 小时前
React Server Components 深度解析:下一代 React 渲染模式
前端·react.js·前端框架
anyup_前端梦工厂3 小时前
React 单一职责原则:优化组件设计与提高可维护性
前端·javascript·react.js
旺旺大力包4 小时前
【 React 】重点知识总结 && 快速上手指南
开发语言·前端·react.js
张开心_kx5 小时前
不要再代码中滥用 useCallback 和useMemo
前端·react.js
Aiolimp6 小时前
React常见Hooks使用(二)
前端·react.js
进取星辰8 小时前
10、Context:跨维度传音术——React 19 状态共享
前端·react.js·前端框架
wfsm8 小时前
react使用01
前端·javascript·react.js
就是我9 小时前
使用React Developer Tools做性能分析
前端·javascript·react.js