组件重新装载时 useSWR 会发起请求

useSWR 重新验证机制完全指南

核心概念:Stale-While-Revalidate

useSWR 的设计基于 "Stale-While-Revalidate"(陈旧但重新验证)模式:

  • Stale(陈旧):已缓存但可能不是最新的数据
  • Revalidate(重新验证):后台检查并更新数据的过程

这种模式让用户能够立即看到数据(即使可能稍旧),同时在后台静默更新,提供最佳的用户体验。

重新验证的完整时机列表

🔄 自动触发时机

1. 组件挂载时(默认)

useSWR('/api/data', fetcher, {
  revalidateOnMount: true // 默认true
})

2. 窗口获得焦点时

useSWR('/api/data', fetcher, {
  revalidateOnFocus: true // 默认true
})

3. 网络重新连接时

useSWR('/api/data', fetcher, {
  revalidateOnReconnect: true // 默认true
})

4. 定时轮询

useSWR('/api/data', fetcher, {
  refreshInterval: 5000 // 每5秒重新验证
})

5. 键值(Key)变化时(总是触发)

// userId变化 → key变化 → 总是重新验证
useSWR(`/api/user/${userId}`, fetcher)

6. 依赖数据变化时

const [page, setPage] = useState(1)
useSWR(() => `/api/data?page=${page}`, fetcher) // page变化时重新验证

🎮 手动触发时机

7. 显式调用 mutate()

const { mutate } = useSWR('/api/data', fetcher)
mutate() // 手动触发重新验证

8. 使用 trigger() 函数

const { trigger } = useSWR('/api/data', fetcher)
trigger() // 强制重新验证

9. 全局重新验证

import { mutate } from 'swr'
mutate(key => key.startsWith('/api/user')) // 重新验证所有匹配的数据

revalidateIfStale: false 的精确含义

🎯 它影响什么?

只影响一种情况:组件挂载时,如果缓存中已有数据,是否要重新验证。

📊 各个时机的具体影响

✅ 仍然会触发的时机(不受影响)

时机 是否触发 控制选项
键值(Key)变化 总是触发
手动调用 mutate() 手动控制
窗口获得焦点 revalidateOnFocus
网络重新连接 revalidateOnReconnect
定时轮询 refreshInterval

❌ 不会触发的时机(受影响)

时机 是否触发 说明
组件挂载(有缓存时) 主要受影响场景
组件重新挂载 同上

🧪 代码验证示例

const { data } = useSWR('/api/data', fetcher, {
  revalidateIfStale: false,    // 只影响挂载时的重新验证
  revalidateOnFocus: true,     // ✅ 焦点时仍然会验证
  revalidateOnReconnect: true, // ✅ 网络重连时仍然会验证
  refreshInterval: 5000        // ✅ 每5秒仍然会轮询
})

// ✅ userId变化时总是会请求新数据
useSWR(`/api/user/${userId}`, fetcher, {
  revalidateIfStale: false
})

// ✅ 手动触发总是有效
const handleRefresh = () => {
  mutate() // 强制重新验证
}
posted @ 2025-09-20 15:28  丁少华  阅读(14)  评论(0)    收藏  举报