You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Query 取消pending或之前发起的未完成请求失败如何解决?

React Query 未触发请求取消的解决方案

你的实现核心问题是在await axios.get执行完成后才给响应对象挂载cancel方法,此时请求已经结束,React Query无法在请求pending阶段获取到取消方法,因此无法触发取消操作。


推荐实现方式(适配React Query v3+ + Axios 0.22+)

React Query的查询函数默认会传入包含signal属性的上下文对象,直接配合Axios原生支持的AbortSignal使用即可,不需要手动维护CancelToken:

const [value, setValue] = React.useState<boolean>(false);

const getData = async (value: number, signal: AbortSignal): Promise<any> => {
  return axios.get(`https://xxxxxx?value=${value}`, {
    signal,
  }).then(res => res.data);
}

const { data: result, status, error, isFetching } = useQuery(
  ['getData', value],
  // 从查询函数上下文拿到signal传给请求方法
  (context) => getData(value, context.signal),
  {
    refetchOnWindowFocus: false,
  }
);

该实现可自动覆盖所有取消场景:

  • 当value变化触发查询key变更时,旧的pending请求会被自动取消
  • 当组件卸载时,关联的pending请求会被自动取消
  • 如需手动批量取消请求,可通过useQueryClient获取实例后调用queryClient.cancelQueries({ queryKey: ['getData'] })

兼容旧版Axios(必须使用CancelToken的场景)

如果你的Axios版本低于0.22不支持AbortSignal,需要给返回的Promise对象挂载cancel方法,而不是给await后的响应对象挂载:

const getData = (value: number): Promise<any> => {
  const CancelToken = axios.CancelToken
  const source = CancelToken.source()
  // 不要加await,直接返回未resolve的Promise实例
  const promise = axios.get(`https://xxxxxx?value=${value}`, {
    cancelToken: source.token,
  }).then(res => res.data);
  // 给Promise实例挂载cancel方法供React Query调用
  (promise as any).cancel = () => {
    source.cancel('Query was cancelled by React Query')
  }
  return promise;
}

内容的提问来源于stack exchange,提问作者Sole

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 14:36:07