React Query 能否用来轮询接口直到获取到指定数据?
可以实现,React Query 原生支持这类长轮询需求,比手动写定时器维护状态更稳定
React Query 提供的 refetchInterval 配置项刚好适配这种「持续请求直到满足终止条件」的场景,还会自动处理组件卸载、页面切后台的轮询清理逻辑,完全不需要手动维护定时器和处理内存泄漏问题。
具体实现步骤
1. 核心逻辑说明
refetchInterval 支持传入函数,你可以在函数内拿到当前接口返回的最新数据,判断是否满足终止条件:
- 满足终止条件:返回
false,直接停止轮询 - 不满足终止条件:返回数字,作为下一次请求的间隔时间(单位为毫秒)
2. 代码示例
假设你有一个查询流程进度的接口,返回字段包含 status(处理状态:processing/success/failed)和 progress(当前进度百分比):
import { useQuery } from '@tanstack/react-query' // 你的接口请求方法 const fetchProcessProgress = async (processId) => { const res = await fetch(`/api/process/${processId}/progress`) return res.json() } function ProcessProgress({ processId }) { const { data, isLoading, error } = useQuery({ // queryKey 要包含唯一标识(如流程ID),不同流程的轮询状态会隔离管理 queryKey: ['processProgress', processId], queryFn: () => fetchProcessProgress(processId), // 轮询核心配置 refetchInterval: (query) => { const currentData = query.state.data // 流程处理成功/失败时终止轮询 if (currentData?.status === 'success' || currentData?.status === 'failed') { return false } // 否则每2秒请求一次接口 return 2000 }, // 可选:页面切到后台时是否继续轮询,默认false refetchIntervalInBackground: true, // 可选:请求失败时的重试次数,默认3次 retry: 3, // 可选:请求失败的重试间隔,单位毫秒 retryDelay: 1000 }) if (isLoading) return <div>加载进度中...</div> if (error) return <div>进度加载失败,请刷新重试</div> return ( <div> <p>当前处理进度:{data.progress}%</p> {data.status === 'success' && <p>✅ 流程处理完成</p>} {data.status === 'failed' && <p>❌ 流程处理失败:{data.errorMsg}</p>} </div> ) }
注意事项
- 组件卸载时 React Query 会自动停止对应轮询,不需要额外写清理逻辑
- 如果需要手动终止轮询,调用
useQuery返回的remove()方法即可,会同时清除当前查询的缓存 - 轮询间隔可以根据业务灵活调整,比如进度到90%之后缩短间隔到500ms,更快拿到最终结果
内容的提问来源于stack exchange,提问作者Ever Dev
相关产品推荐
相关产品推荐

