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

React报错Error saving to hook array: object is not iterable

问题描述

实现点击商品按钮将商品对象存入React Hook管理的数组功能时,持续触发Error saving to hook array: object is not iterable报错。

初始实现代码

let shoppingArray = [];
const shopping = (item) => {
 shoppingArray.push(item);
 console.log(shoppingArray);
 setShoppingBag(...shoppingBag, shoppingArray);
};

...

<ShoppingCartOutlinedIcon className="icons" onClick={() => shopping(item)}></ShoppingCartOutlinedIcon>

控制台报错信息

Uncaught TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))

报错截图

调整后仍失效的代码

将代码修改为如下写法后功能依然无法正常运行:

const [shoppingBag, setShoppingBag] = React.useState([]);

const shopping = (item) => {
  setShoppingBag(...shoppingBag, item);
};
错误原因
  • 核心错误:useState返回的状态更新函数setShoppingBag仅接收1个参数,参数为新的状态值,或返回新状态值的回调函数。两次错误写法都对setShoppingBag传入了多个展开后的参数,React只会识别第一个参数作为新状态,也就是原shoppingBag数组的第一个元素(非数组类型),后续参数直接被忽略。当后续渲染再次尝试对非数组类型的值做展开操作时,就会触发「对象不可迭代」的报错。
  • 第一版代码额外问题:
    • 在组件外部额外声明shoppingArray存储数据,组件重渲染时该变量不会被重置,会引发状态污染
    • 传入整个shoppingArray作为参数,会导致数组嵌套存入状态,不符合追加单个商品的预期
正确实现方案

基础写法

直接将拼接完成的新数组作为唯一参数传入更新函数:

const [shoppingBag, setShoppingBag] = React.useState([]);

const shopping = (item) => {
  setShoppingBag([...shoppingBag, item]);
};

推荐写法(函数式更新)

如果短时间内多次触发添加操作,直接读取外层的shoppingBag可能拿到闭包缓存的旧值,使用函数式更新可以保证始终基于最新状态计算:

const [shoppingBag, setShoppingBag] = React.useState([]);

const shopping = (item) => {
  setShoppingBag(prevShoppingBag => [...prevShoppingBag, item]);
};

内容的提问来源于stack exchange,提问作者Captai-N

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 21:57:23