TanStack Query 的 staleTime 和 gcTime 有什么区别?为什么有缓存还会重新请求?
下面是一段教学模拟,不是真实面试记录。
🧑💻 面试官:请求结果已经在缓存里,切回页面为什么还发请求?
🙋♂️ 我:可能缓存过期被删掉了,把 gcTime 设长一点。
🧑💻 面试官:页面已经先显示缓存结果,说明缓存还在。为什么又要请求?
🙋♂️ 我:可能这份数据被认为不新鲜了。
🧑💻 面试官:那 staleTime 和 gcTime 分别从什么时候计时,控制什么事情?
这里有两个判断:「还要不要相信这份旧数据」和「没人使用时还留多久」。前者看 staleTime,后者看 gcTime。
面试速答(60 秒版)
staleTime 控制数据被认为新鲜的时长。数据变为 stale 后,组件挂载、窗口重新聚焦或网络恢复等事件,可以按配置触发后台请求。
gcTime 则控制查询变为 inactive 后,缓存还能保留多久。它不是从请求成功就开始倒计时,也不决定数据是否新鲜。
所以,缓存还在但已经 stale 时,页面可以先显示旧数据,再后台获取新数据;这不是缓存失效被删除。
另外,staleTime 到期本身不等于立刻请求,轮询、手动请求和主动失效还有各自规则。排查时要同时看查询状态、使用者生命周期和触发事件。

知识点详解:把“新鲜”和“存在”分开看
有缓存,还需要判断能不能继续直接用
假设商品列表一分钟内变化很少,我们配置 staleTime 为两分钟。
请求成功后,两分钟内它被认为 fresh。组件在符合条件的情况下再次使用同一个查询,可以直接读缓存,避免基于陈旧状态的自动重取。
两分钟过去,它变为 stale,但数据没有因此消失。框架是在提醒“这份结果可能需要更新”,不是宣布它已经无效到不能展示。v5 默认行为说明
因此,“页面立刻有内容,网络随后又请求一次”可以是正常的后台更新,而不是缓存没有命中。
gcTime 的时钟,从没人使用开始
继续这个教学例子,配置 gcTime 为五分钟:
| 时间 | 发生什么 | 缓存情况 |
|---|---|---|
| 0 分钟 | 请求成功,页面使用查询 | 数据 fresh,查询 active |
| 2 分钟 | 新鲜时长过去 | 数据 stale,仍在使用 |
| 3 分钟 | 最后一个使用者卸载 | 查询 inactive,开始保留计时 |
| 8 分钟 | 期间没有重新使用 | 达到教学配置的回收时间 |
如果 6 分钟又挂载使用同一查询,尚未回收的数据可以立即展示。由于已经 stale,符合重取条件时还会发起请求。
所以,这里不是从第 0 分钟算到第 5 分钟就删除;更不能因为页面开了半小时,就认为 gcTime 已经自动清空仍被使用的查询。

到期和请求触发,不是同一个事件
staleTime 到期只改变新鲜状态。是否发请求,还需要看挂载、聚焦、重连等触发规则。
轮询由 refetchInterval 等配置控制,不应该理解成 staleTime 自带定时轮询。手动 refetch 也有自己的意义,不能把“fresh”当成任何情况下都不允许请求。
主动 invalidate 会表达数据已经不可信,需要按照配置处理。如果使用特殊的 static 策略,还要单独核对其严格行为,不能与 Infinity 混为一谈。
排查时查看实际的生效配置,而不仅是某个组件文件里的两个时间值。
缓存时间正确,查询身份也可能不正确
假设同一个查询同时使用页码、筛选条件和用户身份,但 Query Key 只写了一个固定字符串。
这样可能拿到另一组条件下的缓存。把 staleTime 调短,最多让错误暴露时间缩短,并没有修正缓存身份。
相反,如果每次渲染都把不稳定的值加入 Key,框架可能认为产生了不同查询,看起来就像“怎么一直不复用缓存”。
因此依次检查:是否为同一个 Key、数据是否存在、是否 fresh、有没有 active observer、什么事件触发请求。这个顺序比只把两个时间都改成无限大更有用。
面试官继续追问
staleTime 是 Infinity,就永远不请求了吗?
不能这样概括。它避免基于自然陈旧的重取,但主动失效、手动 refetch 等还需要看规则。当前版本的 static 与 Infinity 也有区别。
gcTime 比 staleTime 小,有没有错误?
不必然错误。一个描述新鲜状态,一个描述闲置保留。查询如果早早闲置并被回收,下次仍可能需要重新获取,即使原本的新鲜时长还没走完。
应该怎样给列表选时间?
先看变化频率、容许陈旧程度和切换页面的习惯,再做请求与体验评测。用户主动修改后,应进行相应失效或更新缓存,不能只等自然到期。
面试速记卡
- staleTime:决定数据保持 fresh 多久。
- gcTime:决定查询 inactive 后缓存保留多久。
- 缓存命中:可以先显示已有数据,再后台重取。
- 请求时机:陈旧状态与挂载、聚焦、重连等触发规则共同决定。
- 排查顺序:Query Key、数据存在、新鲜状态、使用者与触发事件。
公司面试真题
这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。
浏览公司面试真题 →