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

useEffect清理函数解决组件卸载后状态更新报错的方案咨询

现有实现存在的问题

  • 逻辑错误:取消请求后未区分错误类型,直接读取error.response.status会触发异常。axios主动取消请求时抛出的错误不存在response属性,直接访问status会报Cannot read properties of undefined错误。
  • 冗余逻辑:服务层ProductService.getProducts中的try/catch完全多余,没有做任何额外处理只是原封不动抛出错误,可以直接删除简化代码。

可优化的点

  • 新增取消错误过滤:在请求catch块中通过axios.isCancel()方法过滤主动取消的请求,不做错误日志打印,同时对error.response增加可选链判断,避免读取不存在的属性报错。
  • 增加卸载状态双重校验:除了取消请求外,新增组件是否卸载的标记位,即使请求没有被成功取消,也不会对已卸载组件更新state,兼容后续换用fetch等其他请求库的场景。
  • 替换废弃的CancelToken:axios v0.22.0及以上版本已经将CancelToken标记为弃用,推荐使用符合Web标准的AbortController实现请求取消,通用性更强。

优化后代码示例

组件层代码

const [products, setProducts] = useState([]);

useEffect(() => {
  const controller = new AbortController();
  let isMounted = true;

  const fetchProducts = async () => {
    try {
      const data = await ProductService.getProducts(controller.signal);
      // 更新state前先判断组件是否仍挂载
      if (isMounted) {
        setProducts(data);
      }
    } catch (error) {
      // 跳过主动取消的请求错误
      if (axios.isCancel(error)) return;
      // 可选链避免读取不存在的属性报错
      console.log(error.message, error.response?.status);
    }
  };

  fetchProducts();

  return () => {
    isMounted = false;
    controller.abort();
  };
}, []);

服务层代码(简化后)

const ProductService = {
  getProducts: function (signal) {
    return axios.get(myURL, { signal }).then(res => res.data);
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 02:06:07