React Query 的请求怎么避免重复触发?

Air-丹丹 阅读 2

我在用 React Query 做一个用户列表页,每次组件挂载都会自动发请求,但切换 tab 再回来又会重新请求一次,明明数据没变啊。

我试过把 enabled 设成 false 手动控制,但这样 initialData 就不生效了,而且逻辑变得很绕。有没有办法让 query 在已有缓存的情况下别重复发请求?

我的代码大概是这样的:

const { data } = useQuery({
  queryKey: ['users'],
  queryFn: fetchUsers,
  staleTime: 5 * 60 * 1000, // 5分钟
  cacheTime: 10 * 60 * 1000
})

按理说 staleTime 里应该直接用缓存才对,但它还是每次都重新请求,是我哪里理解错了?

我来解答 赞 0 收藏
二维码
手机扫码查看
1 条解答
爱学习的万华
你这个情况很常见,其实 React Query 的缓存机制比你想象的要复杂点。首先确认下你的 queryKey 是不是完全一致,包括参数顺序,React Query 会把它当作缓存的唯一标识。

关于 staleTime 的理解有点偏差,它控制的是数据过期后是否重新请求,不是是否使用缓存。要实现你想要的效果,需要结合 staleTimerefetchOnMount 这两个参数:

const { data } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
staleTime: 5 * 60 * 1000,
cacheTime: 10 * 60 * 1000,
refetchOnMount: false // 关键在这里
})


另外还有个更精细的控制方式是用 refetchOnMount 的智能模式:
refetchOnMount: 'always' | 'ifStale' | false


默认值是 'always' 所以会一直重新请求,改成 'ifStale' 就会只在数据过期时重新请求。

还有个坑要注意:如果你在开发时用了 React.StrictMode,它会故意重复挂载组件来检测问题,这时候可以把 staleTime 设大点或者关掉严格模式测试下。

我一般习惯这么配:
{
staleTime: 1000 * 60 * 5, // 5分钟
cacheTime: 1000 * 60 * 15, // 15分钟
refetchOnMount: 'ifStale',
refetchOnWindowFocus: false // 切换窗口也不重新请求
}


这样基本就能满足大多数列表页的需求了,数据不会频繁重新请求,用户体验也好。
点赞
2026-03-08 14:20