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

react16中的hooks的底层实现原理

好的 👍,你问的是 React 16 中所有 Hooks 的底层实现和原理
这里我会分几个层次来解释:

  1. React 16 的背景

  2. Hooks 的设计理念

  3. 核心 Hooks 的底层实现思路useStateuseEffectuseContext, …)

  4. React 内部的 Hook 数据结构

  5. 执行流程(函数组件渲染时 Hook 的调用顺序)


1. 背景:React 16 与 Hooks

  • React 16.8 是第一个支持 Hooks 的版本。

  • 目标:让函数组件具备状态(state)和副作用(effect)的能力,替代部分 class 组件逻辑(比如 componentDidMount / componentDidUpdate / componentWillUnmount)。

  • 核心思想通过“调用顺序”来匹配 Hook 与组件的 fiber 节点,避免显式 id


2. Hooks 的设计理念

React Hooks 有几个原则:

  1. 只能在函数组件顶层调用,不能在条件语句或循环里动态调用。

    • 这是因为 Hooks 依赖调用顺序来定位。

  2. 只能在 React 函数组件或自定义 Hook 中调用

  3. 每个组件 fiber 节点维护一个单链表,链表节点就是 Hook 对象。

👉 这就是为什么 eslint-plugin-react-hooks 会强制规则:不要在 if/for 中调用 Hook


3. 常见 Hooks 的底层原理

(1) useState

  • 本质是 useReducer 的语法糖。

  • 内部维护一个 Hook 节点对象(链表的一部分):

type Hook = {memoizedState: any,     // 当前的 statebaseState: any,         // 初始 statequeue: UpdateQueue,     // 更新队列(链表结构)next: Hook | null       // 指向下一个 Hook
}
  • 当你调用 useState(initial) 时:

    • 创建一个更新对象(action)。

    • 挂到 queue 上。

    • 触发 scheduleUpdateOnFiber,进入调度。

    1. React 在当前 fiber 上创建一个 Hook 节点,memoizedState = initial

    2. 返回 [state, dispatch]

    3. dispatch 本质是一个函数:

  • 渲染时,React 会执行 processUpdateQueue,消费 queue,更新 memoizedState


(2) useEffect

  • 保存副作用函数和依赖数组。

  • Hook 节点结构:

type Effect = {tag: HookFlags,          // effect 类型(Passive, Layout 等)create: () => (() => void) | void,  // 副作用函数destroy?: () => void,    // 清理函数deps: any[] | null,      // 依赖next: Effect | null
}
  • 调用 useEffect(fn, deps) 时:

    • 如果 deps 变了,就调用上一次的 destroy(清理),再执行新的 create

    • 如果没变,则跳过。

    1. React 在 Hook 节点里记录 create 和 deps

    2. 在 commit 阶段(DOM 更新后),React 比较新旧依赖:


(3) useLayoutEffect

  • 和 useEffect 类似,但执行时机不同:

    • useLayoutEffect 在 DOM 更新后、浏览器绘制前 执行(同步)。

    • useEffect 在 浏览器绘制后 执行(异步,延迟)。

  • 用于测量 DOM、同步操作。


(4) useContext

  • 获取 Context 的值。

  • 机制:

    • 组件调用 useContext(MyContext) 时,会在 fiber 上记录对 MyContext 的依赖。

    • 当 Context Provider 的值变化时,React 会找到所有依赖它的消费 fiber,触发更新。


(5) useReducer

  • 类似 Redux 的 reducer:

    • useState 底层其实就是 useReducer 的特例:

      useState(initial) === useReducer((s, a) => typeof a === 'function' ? a(s) : a, initial)
      
  • 保存 reducer 和 state,通过 dispatch 触发更新。


(6) useRef

  • 维护一个 { current: any } 对象,整个生命周期内保持引用不变。

  • 实现:只在 Hook 节点里存一个 memoizedState = { current: initialValue },之后不会更新。


(7) useMemo / useCallback

  • 本质是“带缓存的值 / 函数”。

  • Hook 节点保存 value 和 deps

  • 渲染时对比依赖数组:

    • 如果没变,直接返回旧值。

    • 如果变了,重新计算并缓存。


4. React 内部 Hook 数据结构

在 fiber 节点上,每个函数组件对应一个 Hook 链表

type Fiber = {memoizedState: Hook | null; // hook 链表头updateQueue: any;// ...
}
  • renderWithHooks 函数:

    • 进入函数组件渲染时,初始化 currentlyRenderingFiber

    • 每调用一个 Hook,就在链表上走一步,复用或新建节点。

    • 保证 “调用顺序一致 = Hook 顺序一致”。


5. Hook 执行流程总结

  1. 初次渲染

    • 执行函数组件,依次调用 useState / useEffect …

    • 为每个 Hook 创建一个 Hook 节点,挂到 fiber.memoizedState 链表上。

  2. 更新渲染

    • 执行组件时,React 会遍历 fiber.memoizedState 链表。

    • 每次调用 Hook,就拿到对应节点,复用之前的状态。

    • 如果调用顺序错了(比如把 Hook 放到 if 里),链表错位,React 会报错。

  3. 提交阶段(commit phase)

    • 对于 useEffect / useLayoutEffect,会根据依赖比较来执行副作用。

    • 对于 useState / useReducer,会处理更新队列,得到新 state。


✅ 总结:

  • React Hooks 的底层实现是 fiber 节点上的 Hook 链表 + 调用顺序保证

  • 每个 Hook 维护一个小的状态对象,存储 memoizedStatequeuedeps 等。

  • useState 基于更新队列;useEffect 延迟到 commit 阶段执行;useRef 只是一个稳定对象;useMemo / useCallback 做依赖比较。


http://www.dtcms.com/a/420036.html

相关文章:

  • 怎么建设自己淘宝网站首页温州网站设计只找亿企邦
  • 熵的概念及其在机器学习中的应用
  • PCIe协议之低功耗篇之 L1状态
  • nodejs做静态网站淘宝网页版登陆
  • Web打印
  • 前端开发中,关于url的经验总结和注意事项
  • Coze源码分析-资源库-编辑插件-前端源码-核心逻辑
  • 公司网上注册在哪个网站有啥创意可以做商务网站的
  • 校园兼职网站开发用例图互联网招聘网站
  • HarmonyOS 广告服务 ArkTS 实现指南:从激励广告到多形式适配
  • wordpress多站点换域名深圳网址排名
  • 网站存在原理网络营销方式哪些
  • DragonBalls_One008
  • 9月28日星期天今日早报简报微语报早读
  • 网络公司免费做网站wordpress导出全站链接
  • 网站数据泄露我们应该怎么做ps网站首页设计图
  • 辗转相除法(欧几里得算法)探微
  • 【Leetcode hot 100】208.实现Trie(前缀树)
  • 【开题答辩全过程】以 基于Java的网上租车系统的设计与开发为例,包含答辩的问题和答案
  • Linux系统编程深度指南:与内核的对话
  • 资源库建设网站工信部网站 登陆
  • 贵州住房和城乡建设部网站官网网站建设怎样
  • C++IO流学习
  • 网站建设哪里可以学招聘网官网
  • 队列+宽搜(BFS)-515.在每个树行中找最大值-力扣(LeetCode)
  • 网站建设升级的必要性做网站用什么服务器会比较好
  • 摄影网站开发的背景网站设计专题页
  • 网站备案 查询wordpress媒体优化
  • 商业网站的域名后缀是什么wordpress+信息流
  • 邢台网站制作哪里做做网站需要vps吗