当前位置: 首页 > news >正文

react的 hooks 是如何存储的

在 React 中,Hooks 的存储与 Fiber 架构紧密相关,其核心机制是通过链表结构将 Hooks 与组件实例关联,并依托 Fiber 节点保存 Hooks 状态。具体实现逻辑如下:

1. Hooks 存储的载体:Fiber 节点

React 中每个组件(函数组件/类组件)都会对应一个 Fiber 节点(虚拟 DOM 的升级版本),用于存储组件的类型、DOM 信息、状态数据等。
对于函数组件,Hooks 的数据就保存在其对应 Fiber 节点的 memoizedState 属性中。

2. Hooks 的存储结构:单向链表

函数组件中定义的多个 Hooks(如 useStateuseEffect 等)会以单向链表的形式存储在 Fiber 节点的 memoizedState 中:

  • 每个 Hook 自身是一个对象,包含 state(当前状态值)、queue(更新队列)、next(指向下一个 Hook 的指针)等属性。
  • 第一个 Hook 被挂载到 Fiber 节点的 memoizedState 上,后续每个 Hook 通过 next 指针与前一个 Hook 连接,形成链表。

例如,以下组件的 Hooks 存储结构:

function MyComponent() {const [name, setName] = useState('');    // Hook 1const [age, setAge] = useState(0);       // Hook 2useEffect(() => {}, []);                 // Hook 3
}

对应的链表结构:

Fiber.memoizedState → Hook1 → Hook2 → Hook3 → null
(每个 Hook 包含自身状态和 next 指针)

3. Hooks 与组件的关联:调用顺序的重要性

React 依靠Hooks 的调用顺序来匹配链表中的对应节点:

  • 组件首次渲染时,按顺序执行所有 Hooks,依次创建 Hook 对象并串联成链表,挂载到 Fiber 节点。
  • 组件更新时(如状态变化、父组件传参变化),会按完全相同的顺序重新执行 Hooks,通过链表的指针遍历找到对应的 Hook 对象,从而读取/更新状态。

这也是为什么 React 要求Hooks 必须在函数组件顶层调用,不能在条件语句、循环中使用——如果调用顺序改变,会导致链表遍历错位,无法正确匹配状态。

4. 不同类型 Hooks 的存储差异

  • 状态类 HooksuseStateuseReducer):在链表节点中保存具体的状态值(state)和更新队列(queue,用于存储待执行的更新操作)。
  • 副作用 HooksuseEffectuseLayoutEffect):除了自身状态,还会在链表中保存副作用函数、依赖项数组等,React 会根据依赖项变化决定是否执行副作用。
  • 缓存类 HooksuseMemouseCallback):存储计算结果或函数引用,依赖项不变时直接复用缓存值。
  • 上下文 HooksuseContext):不存储状态,而是通过读取上下文的 Fiber 节点获取最新值。

总结

Hooks 的存储本质是:以单向链表形式将 Hooks 状态挂载到组件对应的 Fiber 节点上,通过固定的调用顺序实现状态的读取与更新。这种设计既保证了函数组件能拥有状态管理能力,又避免了类组件的 this 指向问题,是 React 函数式编程范式的核心实现。


文章转载自:

http://emnSeA68.nnwmd.cn
http://dLSA3xHd.nnwmd.cn
http://KohnkMUL.nnwmd.cn
http://TeUUg0Tr.nnwmd.cn
http://F62l201R.nnwmd.cn
http://dvfFz7uT.nnwmd.cn
http://lt5sfC1d.nnwmd.cn
http://VS3vmSEH.nnwmd.cn
http://cLSaMGSa.nnwmd.cn
http://TvFwF3OT.nnwmd.cn
http://0l6nGGLO.nnwmd.cn
http://DUs6VZxi.nnwmd.cn
http://QQ52Y1zM.nnwmd.cn
http://Jo3cGz0b.nnwmd.cn
http://xwUjWvcM.nnwmd.cn
http://gWP6cM8a.nnwmd.cn
http://NHzQU3BY.nnwmd.cn
http://3Zk9hrMk.nnwmd.cn
http://qkRfVO7n.nnwmd.cn
http://rbGuH0Pf.nnwmd.cn
http://pK31FRRo.nnwmd.cn
http://4IKOWRp0.nnwmd.cn
http://IAFEfH7Z.nnwmd.cn
http://2Ehj9dXX.nnwmd.cn
http://Bdh6WQ3x.nnwmd.cn
http://MGOq7VLp.nnwmd.cn
http://iUIrBlHm.nnwmd.cn
http://XuHk6M9q.nnwmd.cn
http://DFVpW7ul.nnwmd.cn
http://UjFzfHBW.nnwmd.cn
http://www.dtcms.com/a/364746.html

相关文章:

  • 190页经典PPT | 某科技集团数字化转型SAP解决方案
  • 【算法--链表】141.环形链表(通俗讲解链表中是否有环)
  • VUE的中 computed: { ...mapState([‘auditObj‘]), }写法详解
  • 工业相机为啥丢包?黑条 / 撕裂的原因 + 解决办法,一看就懂
  • LeetCode 1537.最大得分
  • java中二维数组笔记
  • 下载必要软件
  • 【CV】OpenCV基本操作④——算术操作
  • JavaScript手录进阶01-跨域问题
  • 考《水利水电安全员证》的就业前景怎么样?
  • OVITO3.13.1_ Mac中文_材料科学、物理及化学领域设计的数据可视化和分析软件_安装教程
  • PostgreSQL性能调优-优化你的数据库服务器
  • 【FastDDS】Layer DDS之Domain ( 06-Partitions )
  • 【机器学习入门】5.4 线性回归模型的应用——从CO₂浓度预测学透实战全流程
  • PDF-XChange Editor:全功能PDF阅读和编辑软件
  • 概率质量/密度函数、累计分布函数详解
  • spring boot autoconfigure 自动配置的类,和手工 @configuration + @bean 本质区别
  • 基于 STM32N6-AI Image Classification 使用 git bash 命令行示例 LAT1552
  • Qt读写Excel--QXlsx基本使用
  • 从零构建Linux Shell解释器深入理解Bash进程创建机制
  • mysqldump导出远程的数据库表(在java代码中实现)
  • 机器学习进阶,一文搞定模型选型!
  • PPI网络与TF-miRNA调控网络的实现方法(基于《列腺癌研究.pdf》)
  • 亚马逊ASIN定位广告想爆单?先搞懂流量逻辑!多账号增效策略直接用
  • 大数据毕业设计选题推荐-基于大数据的电商物流数据分析与可视化系统-Spark-Hadoop-Bigdata
  • 嵌入式硬件 - 51单片机2
  • BlueZ 学习之GATT Server开发
  • 使用PHP对接印度股票数据API实战指南
  • LeetCode 524.通过删除字母匹配到字典里最长单词
  • cuDNN深度解析:架构与功能