组件重新装载时 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() // 强制重新验证
}