React Query设置enabled为false后,组件状态变化时useQuery仍自动重新请求的问题排查
兄弟,我仔细扒了你的自定义钩子代码,发现几个很容易踩的坑,这大概率就是你遇到问题的根源,咱们一个个拆解排查:
第一个核心问题:API请求被提前执行了,和useQuery的enabled完全无关
你把requests数组定义在了useQuery的外面,而且直接调用了dashboardApi.getTopProjects(...)——这意味着每次组件重新渲染、这个钩子被执行的时候,不管useQuery的enabled是true还是false,这个API请求都会立刻发出去!
正确的姿势是把请求的调用逻辑放到useQuery的查询函数内部,这样只有当useQuery允许执行时(enabled为true,或者手动触发refetch),才会触发API调用。修改后的代码大概是这样:return useQuery( [queryKeys.account], async () => { // 把请求逻辑移到查询函数内部,避免提前执行 const requests = [ dashboardApi.getTopProjects({ sortBy: TOP_PROJECT_SORT.AverageCost, order: 'desc', limit: '6', }), ] return await Promise.all(requests) }, { enabled: false, onError: (error: AxiosError) => { NotifyService.error(error) }, ...queryOptions, } )第二个排查点:外部传入的queryOptions可能覆盖了enabled设置
你的钩子最后用...queryOptions合并配置,如果调用这个钩子的地方传入了enabled: true,就会直接覆盖你内部设置的enabled: false。举个例子,如果外部这么调用:useGetExportPDFData({ enabled: true })那useQuery最终的enabled就是true,自然会自动触发请求。你可以检查下调用这个钩子的地方有没有传这个参数,或者把内部的enabled配置放到
...queryOptions后面,确保内部设置不会被外部覆盖:{ ...queryOptions, enabled: false, // 把enabled放在后面,强制覆盖外部传入的配置 onError: (error: AxiosError) => { NotifyService.error(error) }, }第三个可能:外部代码触发了该queryKey的重新请求
你可以排查下项目里有没有其他地方用了refetchQueries、invalidateQueries,或者在useMutation的onSuccess钩子中触发了[queryKeys.account]这个queryKey的查询。React Query的refetchQueries默认不会忽略enabled: false的查询,只要指定了对应的queryKey,就会强制触发重新请求。
备注:内容来源于stack exchange,提问作者David Tran

