动态修改TanStack Query的refetchInterval解决自动刷新异常问题
解决Vue-Query/React Query自动刷新切换异常问题
问题原因
你当前的写法存在两个核心问题:
- 把
querySettings的computed值直接传给useQuery,这只会在组件初始化时读取一次配置快照,后续autoRefresh变化时,useQuery无法感知配置更新,导致切换回true时自动刷新失效。 - 当
autoRefresh从true改为false时,已经启动的20秒刷新定时器不会立即取消,所以会触发最后一次额外刷新。
解决方案
通过监听autoRefresh的变化,手动调用useQuery返回的setOptions方法更新配置,同时在关闭自动刷新时取消待执行的请求:
Vue-Query 实现代码
import { ref, watch } from 'vue'; import { useQuery } from '@tanstack/vue-query'; const autoRefresh = ref(true); // 初始化查询,初始开启20秒自动刷新 const getQuery = useQuery({ queryKey: ["vehicles"], queryFn: async () => (await getData.call()).data, refetchInterval: 20000, refetchOnWindowFocus: "always", refetchIntervalInBackground: false, refetchOnReconnect: "always", cacheTime: 20000, }); // 监听autoRefresh切换,动态更新查询配置 watch(autoRefresh, (newStatus) => { // 更新refetchInterval配置 getQuery.setOptions({ refetchInterval: newStatus ? 20000 : false, }); // 关闭自动刷新时,立即取消待执行的刷新请求 if (!newStatus) { getQuery.cancelRefetch(); } });
React Query 等价实现(供参考)
import { useState, useEffect } from 'react'; import { useQuery } from '@tanstack/react-query'; const [autoRefresh, setAutoRefresh] = useState(true); const getQuery = useQuery({ queryKey: ["vehicles"], queryFn: async () => (await getData.call()).data, refetchInterval: 20000, refetchOnWindowFocus: "always", refetchIntervalInBackground: false, refetchOnReconnect: "always", cacheTime: 20000, }); useEffect(() => { getQuery.setOptions({ refetchInterval: autoRefresh ? 20000 : false, }); if (!autoRefresh) { getQuery.cancelRefetch(); } }, [autoRefresh, getQuery]);
关键说明
- 使用
setOptions方法可以让useQuery实时感知配置变化,避免初始化快照导致的失效问题。 - 调用
cancelRefetch()会立即终止当前处于等待状态的刷新请求,解决true转false时的额外刷新问题。 - 无需将整个查询配置放入computed,直接在
useQuery中初始化基础配置,通过监听变量动态修改即可。
内容的提问来源于stack exchange,提问作者Jaisy
相关产品推荐
相关产品推荐

