React-Query除setQueryDefaults外还有其他更新useQuery staleTime的方式吗?
动态更新useQuery staleTime的正确实现方案
首先澄清认知误区:
你提到的第一个直接将响应式
staleTime传入useQuery配置的写法本身是合法可用的,所谓的staleTime变化被忽略本质是配置生效逻辑的差异,不是useQuery没有监听配置变化:
enabled属于查询执行控制类配置,变更后会立刻触发查询启停的逻辑,感知上是即时生效的staleTime属于缓存过期规则配置,仅作用于配置变更后新请求返回的数据,已经存在于缓存中的历史数据的过期时间,是基于数据返回时的staleTime计算生成的,不会因为后续staleTime修改而回溯更新,所以会有「没生效」的错觉
场景1:仅需要新请求使用新的staleTime,历史缓存数据不受影响
直接用你最开始的写法即可,不需要额外逻辑:
function useReactiveStaleTimeQuery() { const [staleTime, setStaleTime] = useState(1000); // staleTime直接传入配置,每次state变更会自动更新到查询配置中 const { data } = useQuery(queryKey, queryFn, { staleTime, notifyOnChangeProps: ["tracked"] }) return data; }
如果需要验证配置是否生效,可以在请求完成后查看query.state.dataUpdatedAt和当前时间的差值,和你设置的staleTime对比,即可确认新的规则已经生效。
补充:staleTime本身也支持传入函数形式,每次查询配置更新时会重新执行函数获取最新值,适合需要动态计算staleTime的场景:
const { data } = useQuery(queryKey, queryFn, { staleTime: () => getCurrentDynamicStaleTime(), })
场景2:修改staleTime后需要立刻让现有缓存按照新规则判断是否过期
可以在staleTime变更时主动触发缓存校验,让符合新过期规则的陈旧数据重新请求:
function useReactiveStaleTimeQuery() { const queryClient = useQueryClient(); const [staleTime, setStaleTime] = useState(1000); useEffect(() => { // staleTime变化后主动触发当前query的缓存有效性校验 queryClient.invalidateQueries(queryKey, { exact: true }); }, [staleTime, queryClient, queryKey]) const { data } = useQuery(queryKey, queryFn, { staleTime, notifyOnChangeProps: ["tracked"] }) return data; }
场景3:修改staleTime后需要完全重置查询实例,使用全新的缓存
将staleTime加入queryKey即可,staleTime变化时会生成全新的查询实例,完全使用新的配置和独立缓存:
function useReactiveStaleTimeQuery() { const [staleTime, setStaleTime] = useState(1000); // 将staleTime作为queryKey的一部分 const queryKey = ['your-business-key', staleTime]; const { data } = useQuery(queryKey, queryFn, { staleTime, notifyOnChangeProps: ["tracked"] }) return data; }
不推荐使用setQueryDefaults的原因
setQueryDefaults是全局配置修改,会覆盖所有匹配对应queryKey的查询的默认配置,影响范围不可控,很容易在其他组件复用同一个queryKey时出现非预期的staleTime逻辑,非全局通用规则不要用这种方式实现。
内容的提问来源于stack exchange,提问作者user11453784
相关产品推荐
相关产品推荐

