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

React函数组件报错:无法在已卸载组件上更新状态

React组件内存泄漏问题修复

错误提示

Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

中文翻译:无法在已卸载的组件上执行React状态更新。这是无效操作,但表明你的应用存在内存泄漏。修复方法:在useEffect的清理函数中取消所有订阅和异步任务。

问题成因

组件的useEffect中发起了异步fetch请求,但未处理组件卸载后的状态更新逻辑。如果请求尚未完成时组件被卸载(比如用户快速跳转页面),请求返回后setData会尝试更新已卸载组件的状态,触发警告并造成内存泄漏。

修复方案

通过AbortController取消未完成的异步请求,同时优化代码细节:

import { useEffect, useState } from "react";
import Carousel from "react-elastic-carousel";

export default function Latest() {
  const [data, setData] = useState([]);

  useEffect(() => {
    // 创建AbortController用于取消请求
    const abortController = new AbortController();
    const signal = abortController.signal;

    fetch("https://test.emkanfinances.net/api/package/show", { signal })
      .then((res) => res.json())
      .then((dataRes) => setData(dataRes))
      .catch((err) => {
        // 仅处理非取消类错误
        if (err.name !== "AbortError") {
          console.error("数据请求失败:", err);
        }
      });

    // 组件卸载时取消请求
    return () => abortController.abort();
  }, []);

  const breakPoints = [
    { width: 1, itemsToShow: 1 },
    { width: 550, itemsToShow: 2, itemsToScroll: 2 },
    { width: 768, itemsToShow: 3 },
    { width: 1200, itemsToShow: 4 },
  ];

  const datashow = data.map((item) => (
    // 添加key属性修复React列表渲染警告
    <div key={item.id} className="card">
      <img
        src={item.package_image}
        className="card-img-top"
        alt={item.details_title_en}
        style={{ width: "100%", height: "20vw", objectFit: "cover" }}
      />
      <div className="card-body">
        <h5 className="card-title">{item.details_title_en}</h5>
        <p className="balneo">
          <i
            className="fa-solid fa-location-dot"
            style={{ paddingRight: "5px" }}
          ></i>
          {item.city_name_en}
        </p>

        <p className="balneo">
          Package Period: <span style={{ fontWeight: "bold" }}> From </span>
          <span style={{ color: "#ff5959" }}> {item.period_from}</span>
          <span style={{ fontWeight: "bold" }}> To </span>{" "}
          <span style={{ color: "#ff5959" }}> {item.period_to}</span>
        </p>
        <div>
          <p className="paragraph">
            <span style={{ color: "var(--yellow-color)" }}>
              {/* 优化星级渲染逻辑,避免重复代码 */}
              {item.package_rate && item.package_rate > 0
                ? Array.from({ length: item.package_rate }, (_, idx) => (
                    <i key={idx} className="fa-solid fa-star"></i>
                  ))
                : ""}
            </span>
          </p>
        </div>
        <p className="card-text">{item.city_details_text1_en}</p>
      </div>
    </div>
  ));

  return (
    <div className="container pt-5 pb-5">
      <h3 className="fw-bold pt-5 text-center mb-5">Featured Listings</h3>
      <Carousel breakPoints={breakPoints} enableAutoPlay autoPlaySpeed={3000}>
        {datashow}
      </Carousel>
    </div>
  );
}

修复说明

  1. 取消异步请求:使用AbortController,组件卸载时自动终止未完成的fetch请求,避免后续状态更新操作
  2. 错误过滤:捕获并忽略请求取消导致的AbortError,减少控制台无效报错
  3. 代码优化:
    • 给列表项添加key属性,符合React列表渲染规范
    • 重构星级渲染逻辑,用Array.from替代多层嵌套的三元判断,简化代码
    • 统一使用React标准属性className替换原生class

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 05:15:27