React Query调用refetch后API返回新数据但缓存未更新
Query Key 生成逻辑错误
你的queryKey里用了Items by ${filter}字符串拼接方式,如果filter是对象类型(比如包含多维度筛选条件的对象),${filter}会被默认转成[object Object]——不管filter内容怎么变化,这部分字符串始终一致,导致React Query判定为同一个查询,即使实际请求参数已经改变。正确的做法是把filter直接作为queryKey的数组元素,比如:queryKey: ["Items list", filter, user.id]另外要检查
user.id和filter在refetch时是否和初始查询时完全一致,如果这些值在创建新项后发生了变化,会导致更新的是另一个独立的缓存条目,组件依然读取旧queryKey对应的缓存数据。闭包导致queryFn使用旧参数
虽然useQuery会根据queryKey变化重新执行,但如果complexQueryFunction内部自带缓存逻辑,或者queryFn没有捕获到最新的filter/user.id,可能导致请求用了旧参数发起。可以在queryFn里临时打印参数,确认每次refetch时使用的都是最新的筛选条件和用户ID。select函数(若使用)未正确处理新数据
如果你的自定义Hook实际使用了select选项做数据转换(简化代码中未体现),要检查select函数是否正确处理了新的响应数据。比如select函数依赖外部状态但没加入依赖数组,或者转换逻辑错误,都会导致返回的data始终是旧值。响应数据被中间件篡改
虽然你看到API返回了新项,但要确认数据在到达React Query之前没有被修改。比如axios拦截器、全局响应处理逻辑,有没有过滤掉新创建的项,或者修改了数据结构,导致React Query最终接收到的是不完整的数据。缓存条目冲突或重复
打开React Query DevTools查看所有缓存条目,检查是否存在多个key相似的缓存项。如果不同组件使用useItemsQuery时,filter或user.id存在差异,会生成不同的queryKey,各自维护独立缓存。比如组件1的filter是"active",组件2的filter是"all",refetch其中一个不会影响另一个的缓存内容。React Query配置的特殊设置
检查你的queryClient默认配置,是否设置了过长的staleTime(比如设为Infinity),导致React Query认为数据始终是新鲜的,即使手动refetch也不更新缓存?不过手动refetch通常会绕过staleTime,这个可能性较低,但可以排查确认。另外有没有开启keepPreviousData,如果queryKey变化会保留旧数据,但你的场景是queryKey未变化,所以这个可能性不大。
内容的提问来源于stack exchange,提问作者Seth Lutske

