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

React更新状态时重复发起API且旧请求未终止导致页面卡顿如何解决

解决方案

核心思路是每次发起新的API请求前,终止上一次未完成的旧请求,可以借助浏览器原生的AbortController实现,同时修复代码里的异步 setState 取值问题,具体修改步骤如下:

步骤1:在组件内初始化AbortController实例

在构造函数中声明变量存储控制器实例,用于后续终止请求,同时组件卸载时主动终止未完成的请求,避免内存泄漏:

constructor(props) {
  super(props);
  this.state = {
    startDate: null,
    endDate: null
  };
  // 存储请求控制器
  this.requestController = null;
}

componentWillUnmount() {
  // 组件卸载时终止未完成的请求
  if (this.requestController) {
    this.requestController.abort();
  }
}

步骤2:改写fetchData方法,绑定终止信号

调用接口时把AbortController生成的signal传入请求配置,每次发起新请求前先终止上一次的请求:

fetchData = async (start, end) => {
  // 先终止上一次未完成的请求
  if (this.requestController) {
    this.requestController.abort();
  }
  // 新建控制器用于本次请求
  this.requestController = new AbortController();
  const signal = this.requestController.signal;

  try {
    // 把signal传入fetch配置(如果用axios的话对应传入cancelToken逻辑类似)
    const res = await fetch(`你的接口地址?start=${start}&end=${end}`, {
      signal: signal
      // 其他请求配置保持不变
    });
    const data = await res.json();
    // 原有处理返回数据的逻辑保持不变
  } catch (err) {
    // 主动abort触发的异常不需要处理,避免页面报错
    if (err.name !== 'AbortError') {
      console.error('请求出错:', err);
    }
  }
}

步骤3:修复updateDate的异步取值问题

setState是异步执行的,连续调用setState后直接读取state可能拿到的是旧值,直接把传入的start、end参数传给fetchData即可,不需要从state取值:

updateDate = (start, end) => {
  this.setState({
    startDate: start,
    endDate: end
  }, () => {
    // 写在setState的回调里可确保state更新后再请求,也可以直接用参数调用更简单
    this.fetchData(start.startDate, end.endDate);
  });
}

修改完成后只有最新的请求会被处理,旧请求会被直接终止,不会占用带宽和渲染资源,卡顿问题即可解决。如果项目用的是axios而非原生fetch,用axios自带的CancelToken实现请求取消,逻辑和上述方案完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 07:18:00