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

React数组状态插入元素时数据持续重复,如何修复?

解决方案

1. 给useEffect添加正确的依赖数组

你的核心问题确实是useEffect未设置依赖数组,导致组件每次渲染都会重复执行axios请求,进而持续往state数组中插入重复数据。结合你的业务逻辑(根据pid获取对应产品),应将pid作为依赖项传入数组,这样只有当pid发生变化时,才会重新发起请求:

const [data, setData] = useState([])

const addData = (newData) => {
   console.log(newData)
   // 用函数式更新确保拿到最新的prevData
   setData(prevData => [...prevData, newData]);
};

useEffect(() => {
  // 新增AbortController,避免组件卸载时的请求内存泄漏
  const controller = new AbortController();
  const signal = controller.signal;

  axios
    .get(`http://localhost:3000/api/products/${pid}`, { signal })
    .then((res) => {
      addData(res.data);
    })
    .catch((err) => {
      // 忽略请求取消的错误
      if (err.name !== 'CanceledError') {
        console.log(err);
      }
    });

  // 清理函数:组件卸载或依赖变化时取消请求
  return () => controller.abort();
}, [pid]); // 此处添加依赖数组,仅在pid变化时执行请求

2. 解决console.log(data)看不到最新值的问题

你在addData里直接console.log(data)会输出旧状态值,因为React的setState是异步更新的,状态不会立即修改。如果需要查看最新的data状态,可以新增一个监听data变化的useEffect:

useEffect(() => {
  console.log('最新的data状态:', data);
}, [data]);

额外优化建议:单个产品数据无需用数组state

从请求地址/api/products/${pid}来看,你应该是获取单个产品详情,这种场景下用数组state没必要,直接用对象state更贴合业务:

const [product, setProduct] = useState(null);

useEffect(() => {
  const controller = new AbortController();
  const signal = controller.signal;

  axios
    .get(`http://localhost:3000/api/products/${pid}`, { signal })
    .then((res) => {
      setProduct(res.data);
    })
    .catch((err) => {
      if (err.name !== 'CanceledError') {
        console.log(err);
      }
    });

  return () => controller.abort();
}, [pid]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 12:57:06