为何调用useQuery的remove方法后会触发持续重复请求?
问题:调用useQuery的remove()方法后,定时请求仍持续触发?
我有一个每2秒从URL获取数据的React Query示例,代码如下,运行正常,控制台每2秒打印一次fetching:
const fetchData = async () => { console.info('fetching'); const result = (await api.get(`/`)).data; return result.data; }; useQuery(['mykey'], fetchData, { refetchInterval: 2000, });
当我想停止定时请求时,尝试使用useQuery返回的remove()方法(文档说明其作用为“将查询从缓存中移除”),修改后的代码如下:
const { remove } = useQuery(['mykey'], fetchData, { refetchInterval: 2000, }); // ... 执行操作后调用remove停止定时请求: remove();
但调用remove()后,fetchData()反而被持续调用,控制台被fetching信息刷屏。请问我哪里操作错误?
解答
核心问题:remove()的作用不是停止定时查询
remove()方法仅负责将查询的缓存数据从React Query的缓存中移除,它不会终止查询本身的定时重取逻辑。甚至因为缓存被清空,React Query会认为该查询没有有效数据,反而触发更频繁的重新请求,这就是控制台刷屏的原因。
正确停止定时请求的三种方案:
1. 动态控制refetchInterval参数
通过状态变量切换refetchInterval的值,需要停止时将其设为false或0:
import { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; const fetchData = async () => { console.info('fetching'); const result = (await api.get(`/`)).data; return result.data; }; const MyComponent = () => { const [stopRefetch, setStopRefetch] = useState(false); const { data } = useQuery(['mykey'], fetchData, { refetchInterval: stopRefetch ? false : 2000, }); // 停止定时请求的触发逻辑 const handleStop = () => { setStopRefetch(true); }; return ( <button onClick={handleStop}>停止定时请求</button> ); };
2. 使用cancelQueries方法取消查询
从queryClient实例调用cancelQueries,直接取消指定key的查询任务:
import { useQuery, useQueryClient } from '@tanstack/react-query'; const fetchData = async () => { console.info('fetching'); const result = (await api.get(`/`)).data; return result.data; }; const MyComponent = () => { const queryClient = useQueryClient(); const { data } = useQuery(['mykey'], fetchData, { refetchInterval: 2000, }); // 停止定时请求的触发逻辑 const handleStop = () => { queryClient.cancelQueries(['mykey']); }; return ( <button onClick={handleStop}>停止定时请求</button> ); };
3. 通过enabled选项禁用查询
将enabled设为false会完全禁用查询,包括所有重取逻辑:
import { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; const fetchData = async () => { console.info('fetching'); const result = (await api.get(`/`)).data; return result.data; }; const MyComponent = () => { const [isQueryEnabled, setIsQueryEnabled] = useState(true); const { data } = useQuery(['mykey'], fetchData, { refetchInterval: 2000, enabled: isQueryEnabled, }); // 停止定时请求的触发逻辑 const handleStop = () => { setIsQueryEnabled(false); }; return ( <button onClick={handleStop}>停止定时请求</button> ); };
内容的提问来源于stack exchange,提问作者Mar Tijn
相关产品推荐
相关产品推荐

