当 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重新执行,获取最新数据
相关推荐
skywalk81631 分钟前
Kotti Next的tinyfrontend前端模仿Kotti 首页布局还是不太好看,感觉比Kotti差一点
前端
RopenYuan2 小时前
FastAPI -API Router的应用
前端·网络·python
走粥2 小时前
clsx和twMerge解决CSS类名冲突问题
前端·css
Purgatory0013 小时前
layui select重新渲染
前端·layui
weixin199701080163 小时前
《中国供应商商品详情页前端性能优化实战》
前端·性能优化
九皇叔叔4 小时前
003-SpringSecurity-Demo 统一响应类
java·javascript·spring·springsecurity
赵孝正5 小时前
学习的本质是一个工程闭环:从模仿到内化的四阶段方法论(附风电实战案例)
前端·数据库·学习
低代码布道师5 小时前
纯代码实战:MBA培训管理系统 (十四) ——用户管理(批量选择与批量删除)
javascript·nextjs