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

React中如何在发起新请求后取消旧异步请求的状态更新

解决React中请求竞态导致的状态覆盖问题

你的问题属于典型的请求竞态条件:当多个异步请求并行时,先发起的请求后完成,会覆盖后发起请求已更新的状态。下面提供两种可靠的解决方式:

方案一:使用AbortController取消旧请求(推荐)

现代浏览器和fetch API支持AbortController,可以直接终止未完成的旧请求,从根源避免无效的状态更新。

import { useState, useRef } from 'react';

const [usersData, toggleUsersData] = useState({});
// 用ref存储当前请求的控制器
const abortControllerRef = useRef(null);

async function queryAndChange(filter_type) {
  // 如果有未完成的旧请求,先取消
  if (abortControllerRef.current) {
    abortControllerRef.current.abort();
  }

  // 创建新的控制器
  const controller = new AbortController();
  abortControllerRef.current = controller;

  try {
    // 把信号传给fetch
    const response = await fetch(`你的接口地址?filter=${filter_type}`, {
      signal: controller.signal
    });
    const new_state = await response.json();
    // 只有当前请求未被取消时才更新状态
    toggleUsersData(new_state);
  } catch (error) {
    // 捕获取消请求的错误,避免控制台报错
    if (error.name !== 'AbortError') {
      console.error('请求失败:', error);
    }
  } finally {
    // 请求完成后清空控制器引用
    if (abortControllerRef.current === controller) {
      abortControllerRef.current = null;
    }
  }
}

方案二:用请求标记忽略旧结果

如果你的环境不支持AbortController,可以在组件内维护一个标记,记录当前最新的请求标识,仅当请求完成时的标识与最新标识一致时才更新状态。

import { useState, useRef } from 'react';

const [usersData, toggleUsersData] = useState({});
// 用ref存储当前最新的请求ID
const latestRequestIdRef = useRef(0);

async function queryAndChange(filter_type) {
  // 生成当前请求的唯一ID
  const currentRequestId = ++latestRequestIdRef.current;

  try {
    const new_state = await fetch(`你的接口地址?filter=${filter_type}`).then(res => res.json());
    // 只有当前请求是最新的,才更新状态
    if (currentRequestId === latestRequestIdRef.current) {
      toggleUsersData(new_state);
    }
  } catch (error) {
    console.error('请求失败:', error);
  }
}

两种方案对比

  • 方案一更高效:直接终止旧请求,节省网络带宽和服务器资源,适合大多数现代浏览器环境。
  • 方案二更兼容:不依赖浏览器API,适合需要兼容旧环境或者无法取消请求的场景(比如某些第三方SDK接口)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 18:01:05