React Query 的 useQuery 为什么在组件多次渲染时重复请求?
我在一个列表组件里用 useQuery 获取数据,明明传了相同的 queryKey,但每次父组件状态更新导致重渲染时,它都会重新发请求,不是应该缓存吗?
我试过加 staleTime,也确认了 queryKey 没变,但还是没用。是不是哪里配置错了?
const { data } = useQuery({
queryKey: ['users'],
queryFn: () => fetch('/api/users').then(res => res.json()),
staleTime: 1000 * 60 * 5, // 5分钟
});
refetchOnWindowFocus: true,而且每次组件重渲染时如果检测到“可能 stale”,就会触发 refetch。你加了
staleTime是对的,但注意:React Query 的默认staleTime是 0!你写 5 分钟是对的,但要确认有没有被其他地方覆盖了(比如全局配置没生效,或者 queryClient 初始化时没传)。不过更常见的坑是:父组件重渲染时,
useQuery的queryFn被重新创建了,哪怕queryKey没变,React Query 也会认为“函数变了,可能结果也变了”,于是触发请求。所以关键点是:
queryFn必须用useCallback或者直接提成外部函数,保证引用稳定。比如这样改:
或者用
useCallback包一下(虽然没必要,因为函数体没依赖):再检查下你有没有全局配置里把
staleTime覆盖成 0,或者有没有useQuery的其他参数(比如enabled、refetchOnMount)在捣乱。代码放这了,你试试看。要是还不行,八成是父组件传了个新对象当
queryKey(比如['users', someObject],每次someObject都是新引用),这种也容易踩。