React Query 中的 staleTime 和 cacheTime
问题描述
在使用 React Query 进行数据缓存时,很多开发者对 staleTime
和 cacheTime
的使用感到困惑。特别是当需要将 API 数据在首次获取后在缓存中保存 2 分钟,无论组件是否挂载或卸载,在这段时间内都不希望再次发起 API 请求。
解决方案
核心概念理解
staleTime
和 cacheTime
在 React Query 中承担着不同的职责:
staleTime:数据新鲜度控制
- 作用:决定数据在多长时间内被认为是"新鲜"的
- 类比:类似于 HTTP 头中的
Cache-Control: max-age=120
- 效果:在
staleTime
设置的时间内,React Query 不会发起新的网络请求 - 默认值:0(立即变为陈旧)
cacheTime:缓存垃圾回收控制
- 作用:决定未使用的查询数据在缓存中保存的时间
- 效果:当查询不再被任何组件使用时(所有使用该查询的组件都已卸载),数据会在
cacheTime
设置的时间后被垃圾回收 - 默认值:5分钟
正确的配置方式
要实现"首次获取数据后2分钟内不发起API请求"的需求,应该这样配置:
javascript
const query = useQuery(
["getUserList"],
getUserList,
{
staleTime: 120000, // 数据保持新鲜2分钟
cacheTime: 300000 // 缓存保留5分钟(默认值)
}
);
可视化理解流程
查看数据获取流程图
常见误区澄清
重要提醒
staleTime
控制的是数据的新鲜度,而不是自动重新获取数据的时间间隔。即使数据标记为陈旧,React Query 也不会立即重新获取,除非满足特定条件(如窗口重新获得焦点、组件重新挂载等)。
如果需要定期重新获取数据,应该使用 refetchInterval
:
javascript
const query = useQuery(
["getUserList"],
getUserList,
{
staleTime: 120000,
refetchInterval: 120000 // 每2分钟重新获取数据
}
);
实际应用场景
场景一:实时性要求不高的数据
javascript
// 用户配置信息,不需要频繁更新
useQuery(["userProfile"], fetchUserProfile, {
staleTime: 5 * 60 * 1000, // 5分钟内使用缓存
cacheTime: 30 * 60 * 1000 // 30分钟后清理缓存
});
场景二:频繁变化的实时数据
javascript
// 实时股价信息,需要频繁更新
useQuery(["stockPrice"], fetchStockPrice, {
staleTime: 1000, // 1秒后就视为陈旧
refetchInterval: 2000, // 每2秒重新获取
refetchOnWindowFocus: true // 窗口聚焦时重新获取
});
最佳实践
- 合理设置 staleTime:根据数据的实际变化频率设置合适的过期时间
- cacheTime 通常无需修改:除非有特殊的内存管理需求,否则保持默认的5分钟即可
- 组合使用缓存策略:结合
refetchOnWindowFocus
、refetchOnReconnect
等选项实现最佳用户体验 - 考虑用户体验:对于重要但变化不频繁的数据,设置较长的
staleTime
可以减少不必要的请求
专业建议
在开发过程中,可以使用 React Query Devtools 来直观地查看缓存的状态、数据的过期情况,这有助于更好地理解和调试缓存行为。
通过正确理解和使用 staleTime
和 cacheTime
,你可以有效地管理应用的数据缓存策略,既提升了用户体验,又减少了不必要的网络请求。