Sunday面试指南

TanStack Query 的 staleTime 和 gcTime 有什么区别?为什么有缓存还会重新请求?

下面是一段教学模拟,不是真实面试记录。

🧑‍💻 面试官:请求结果已经在缓存里,切回页面为什么还发请求?

🙋‍♂️ 我:可能缓存过期被删掉了,把 gcTime 设长一点。

🧑‍💻 面试官:页面已经先显示缓存结果,说明缓存还在。为什么又要请求?

🙋‍♂️ 我:可能这份数据被认为不新鲜了。

🧑‍💻 面试官:那 staleTime 和 gcTime 分别从什么时候计时,控制什么事情?

这里有两个判断:「还要不要相信这份旧数据」和「没人使用时还留多久」。前者看 staleTime,后者看 gcTime。

面试速答(60 秒版)

staleTime 控制数据被认为新鲜的时长。数据变为 stale 后,组件挂载、窗口重新聚焦或网络恢复等事件,可以按配置触发后台请求。

gcTime 则控制查询变为 inactive 后,缓存还能保留多久。它不是从请求成功就开始倒计时,也不决定数据是否新鲜。

所以,缓存还在但已经 stale 时,页面可以先显示旧数据,再后台获取新数据;这不是缓存失效被删除。

另外,staleTime 到期本身不等于立刻请求,轮询、手动请求和主动失效还有各自规则。排查时要同时看查询状态、使用者生命周期和触发事件。

staleTime 和 gcTime:两只时钟:新鲜与存在分开判断

知识点详解:把“新鲜”和“存在”分开看

有缓存,还需要判断能不能继续直接用

假设商品列表一分钟内变化很少,我们配置 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、数据存在、新鲜状态、使用者与触发事件。

公司面试真题

这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。

浏览公司面试真题 →
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历