当 React 组件调用自定义 hooks,hooks 又调用其他 hooks 时,状态变化如何传播?

当 React 组件调用自定义 hooks,hooks 又调用其他 hooks 时,状态变化如何传播?

案例分析

typescript 复制代码
// 调用链: React App → Component → useQuote → useAnotherQuote
React App {
  return <Component />
}

Component {
  const quoteResult = useQuote();  // 调用自定义hook
}

useQuote() {
  const anotherQuoteRes = useAnotherQuote();  // 调用另一个hook
  const quoteRes = useSWR(key, fetcher);    // 调用useSWR
}

useAnotherQuote() {
  const { data, isLoading } = useSWR(key, fetcher);  // 调用useSWR
}

React Hooks 基本机制

1. Hook 状态存储位置

typescript 复制代码
// Hook 状态绑定到调用组件
Component 组件实例 = {
  hookStates: [
    useQuote中的useSWR状态,
    useAnotherQuote中的useSWR状态,
    // ... 其他hook状态
  ]
}

2. Hook 执行规则

  • Hook 只在 Component 渲染时执行
  • Component 不渲染 = hooks 不执行
  • Hook 产生的状态独立于 hook 函数的执行周期,状态更新会触发 Component 重新渲染

useSWR 全局缓存机制

双层存储架构

typescript 复制代码
// 第一层:React Hook 状态(组件级别)
Component {
  hookStates: [useSWRHookState]  // 绑定到组件生命周期
}

// 第二层:全局缓存(应用级别) 
globalCache = Map {
  'key1': {
    data: {...},
    subscribers: Set([setState1, setState2]),  // 多组件订阅
    timer: setInterval(...),  // 定时器常驻
    fetcher: fetcherFunction
  }
}

Key 复用策略

typescript 复制代码
// 相同 key = 复用缓存
useSWR(['api', 'user', 1], fetcher)  // 创建缓存
useSWR(['api', 'user', 1], fetcher)  // 复用缓存

// 不同 key = 新建缓存
useSWR(['api', 'user', 2], fetcher)  // 新建缓存

状态变化传播机制

核心原理:整体重新渲染

typescript 复制代码
useAnotherQuote内的useSWR状态变化
    ↓
React检测到状态变化 
    ↓
**触发 Component 重新渲染**  // 关键点
    ↓  
Component 重新渲染 → 重新执行所有代码
    ↓
重新执行: useQuote() → useAnotherQuote()
    ↓
获取最新状态(从全局缓存)

实际执行时机

触发组件重新渲染的情况

  1. 状态变化 : useState, useSWR 等返回新值
  2. 依赖变化 : useEffect, useMemo 依赖项变化
  3. 父组件重新渲染: 导致子组件重新渲染
  4. 定时器更新 : useSWRrefreshInterval 触发

定时器自动刷新

typescript 复制代码
useSWR(key, fetcher, {
  refreshInterval: 30_000,  // 每30秒自动刷新
  dedupingInterval: 15_000  // 15秒内去重
});

// 执行流程:
// 1. Component 不重新渲染
// 2. useSWR定时器触发数据获取  
// 3. 新数据返回,触发 Component 重新渲染
// 4. 所有hooks重新执行,获取最新数据
相关推荐
拉不动的猪几秒前
# 关于初学者对于JS异步编程十大误区
前端·javascript·面试
玖釉-5 分钟前
解决PowerShell执行策略导致的npm脚本无法运行问题
前端·npm·node.js
Larcher39 分钟前
新手也能学会,100行代码玩AI LOGO
前端·llm·html
徐子颐1 小时前
从 Vibe Coding 到 Agent Coding:Cursor 2.0 开启下一代 AI 开发范式
前端
小月鸭1 小时前
如何理解HTML语义化
前端·html
jump6801 小时前
url输入到网页展示会发生什么?
前端
诸葛韩信2 小时前
我们需要了解的Web Workers
前端
brzhang2 小时前
我觉得可以试试 TOON —— 一个为 LLM 而生的极致压缩数据格式
前端·后端·架构
yivifu2 小时前
JavaScript Selection API详解
java·前端·javascript
这儿有一堆花2 小时前
告别 Class 组件:拥抱 React Hooks 带来的函数式新范式
前端·javascript·react.js