react-query适配fetch却不适配axios?如何解决异常问题
解决Axios适配React-Query的两个问题
问题1:浏览器空闲时频繁发起API请求
核心原因
React-Query要求queryFn每次调用都返回全新的Promise实例。如果你的queryFn复用了同一个Promise(比如把Axios请求提前定义在函数外部),或者写法导致React-Query无法正确识别请求状态,就会触发重复请求。
修复写法
错误示例(会复用Promise):
// 错误:提前执行Axios请求,queryFn每次返回同一个Promise const axiosPromise = axios.get('/api/data').then(res => res.data); const { data } = useQuery(['data'], () => axiosPromise);
正确示例(每次调用都创建新请求):
// 正确:每次调用queryFn都发起新的Axios请求 const { data } = useQuery(['data'], () => axios.get('/api/data').then(res => res.data) );
另外,若不需要空闲时自动刷新,可手动关闭React-Query的默认配置:
const { data } = useQuery(['data'], queryFn, { refetchOnWindowFocus: false, // 窗口聚焦时不重新请求 refetchOnMount: false, // 组件挂载时不重新请求(按需设置) refetchOnReconnect: false // 网络重连时不重新请求(按需设置) });
问题2:queryDependencies变更时未正常更新
核心原因
React-Query通过queryKey的变化判断是否需要重新执行queryFn。如果依赖项未包含在queryKey中,或者queryFn未正确使用依赖项,React-Query无法感知变化,也就不会触发更新。
修复写法
错误示例(依赖项不在queryKey中):
const [userId, setUserId] = useState(1); // 错误:queryKey不包含userId,userId变更时不会触发重新请求 const { data } = useQuery(['user'], () => axios.get(`/api/user/${userId}`).then(res => res.data) );
正确示例(依赖项加入queryKey):
const [userId, setUserId] = useState(1); // 正确:queryKey包含userId,userId变更时自动重新请求 const { data } = useQuery(['user', userId], () => axios.get(`/api/user/${userId}`).then(res => res.data) );
若依赖项是复杂对象,建议用useCallback包裹queryFn,避免闭包问题导致依赖未更新:
const fetchUser = useCallback(({ queryKey }) => { const [, userId] = queryKey; return axios.get(`/api/user/${userId}`).then(res => res.data); }, []); const { data } = useQuery(['user', userId], fetchUser);
额外注意点
- Axios响应结构为
{ data, status, ... },需在queryFn中返回res.data,和Fetch的res.json()行为对齐,避免React-Query处理异常数据。 - 若使用Axios拦截器,确保不会重复调用
resolve/reject,避免干扰Promise状态判断。
内容的提问来源于stack exchange,提问作者Rahul Krrishna
相关产品推荐
相关产品推荐

