- Published on
React Hooks源码解读
- Authors
- Name
- noodles
- 每个人的花期不同,不必在乎别人比你提前拥有
React在函数组件中引入了Hooks机制使函数组件拥有了类组件的生命周期能力(本质上有差异),本文主要通过源码和图文的方式用最简化的方式来阐述React Hooks的实现原理.
前置知识
Fiber
React为了实现时间切片,将页面的组件节点都进行了新的抽象-Fiber.通过引入Fiber结构React可以更好的实现组件更新的调度.Fiber结构主要有以下几种类型的结构:
- Fiber节点的链表连接结构,在组件更新时候需要依赖这些属性
- 动态的运行数据(updateQueue,memoizedState)等,在渲染更新的时候会利用这些属性存储需要更新的操作和数据.Hooks的实现就是依赖这块的结构.
- Lanes 这里主要定义任务的优先级,Fiber Reconciler实现了一套新的优先级更新机制,这块在之后的文章会再介绍.
fiber单链表结构的一些优点:
- 可中断和恢复的任务 单链表结构允许React在多个帧中中断和恢复渲染任务,通过将任务切分小的单元实现时间切盼,这样有助于提高用户界面响应性和避免出现卡顿
- 优先级控制 可以通过链表实现高优先级任务的优先执行
- 轻量化和内存管理 单链表对比双链表相对轻量,降低内存的占用
- 独立性 每个节点的处理相对独立,不影响其他节点
update
react在处理更新中引入了update的概念,在触发更新的时候React将update插入到对应的updateQueue中然后调度页面的渲染更新.最后通过updateQueue的执行来完成更新.
React Fiber Reconciler
React为了实现更新可中断等特性,在具体的渲染过程中会维护两个数据结构:
- current Fiber树结构 当前展示的页面结构
- workInprogress树结构 在更新中添加了更新但是没有渲染到页面的结构
Reconciler渲染过程
render阶段
render阶段主要根据已有的Fiber节点构造对应的workInProgress节点 这个阶段实现了
- 任务的中断
- 优先级任务处理
- 生成effectList等逻辑
commit阶段
- before mutation: DOM即将更新
- mutation:渲染 DOM
- 根据 effectList 的 tag 标注进行 DOM 操作
- 更新、删除、替换 DOM 元素
- layout:执行 DOM 操作后的逻辑
- 执行 useLayoutEffect
- 进行 current 和 workInProgress 的替换
Hook的数据结构
Hooks实现思路


图解hooks的实现思路
Mount阶段Hooks的实现逻辑
Update阶段Hooks的实现逻辑

源码解析hooks的实现思路
以下主要以useState这个hook来分析React在mount阶段和update阶段的源码实现.
mount阶段源码分析
- 根据initialState初始化memoizedState和更新queue
- 返回memoizedState和更新函数(绑定了当前的hook的queue)
update阶段源码分析
在使用useState返回的回调触发页面更新的时候是调用的dispatchAction函数

在组件更新执行到对应的函数组件的时候,会执行对应hook的update阶段对应的hook逻辑.useState对应的就是updateState. 从updateState的代码可以看出useState底层是使用的useReducer代码逻辑.这样具体的更新逻辑就在updateReducer中了!!!

在组件更新执行到对应的函数组件的时候,会执行对应hook的update阶段对应的hook逻辑.useState对应的就是updateState. 从updateState的代码可以看出useState底层是使用的useReducer代码逻辑.这样具体的更新逻辑就在updateReducer中了!!!

updateReducer主要逻辑如下:
- 根据fiber上存储的hook链表获取到当前的hook,hook的更新queue
- 循环执行hook的更新queue,将执行结果保存到hook的数据结构上
- 返回处理结果和更新函数
以上梳理完了React Hook的源码执行流程,也能解决开发中的一些疑问:
- 比如hook的添加为什么不能使用条件语句 因为前后会导致hook的链表无法对应