React中使用useState更新嵌套数组对象的产品qty值
React中更新嵌套数组对象的产品qty属性
需要通过点击事件接收catid和产品id(data.prodid),更新useState管理的嵌套数组中对应产品的qty属性。初始数据结构如下:
let categoriesInfo = [ { catid: 'category-1', catName: 'Fun Stuff', product: [ { id : 1, name: 'candy', qty: 0, }, { id : 2, name: 'cookie', qty: 0, } ] }, { catid: 'category-2', catName: 'Fun Stuff2', product: [ { id : 1, name: 'candy2', qty: 0, }, { id : 2, name: 'cookie2', qty: 0, } ] } ]
已通过useState初始化状态:
const [productData, setProductData] = useState(categoriesInfo);
现有代码逻辑错误,无法正确更新qty,错误代码如下:
const x = (data) =>{ console.log(productData) const y = productData.map(obj => { if (obj.catid == data.catid && obj.product[1-data.prodid].id == data.prodid) { console.log(obj.product[1-data.prodid].name) return {...obj.product[1-data.prodid], qty : 2}; //something like this } return obj; }); setProductData(y); }
错误原因分析
- 遍历分类数组时,匹配到目标分类后返回单个产品对象,而非完整的分类对象,直接破坏了原数组结构
- 使用
1-data.prodid定位产品属于硬编码逻辑,仅适用于产品id为1、2的特殊场景,不具备通用性 - 未正确保留原对象的其他属性,违反了React状态更新的不可变性原则
正确实现方法
需要逐层遍历嵌套结构,找到目标分类和产品后,创建新对象更新qty,同时保留其他所有属性:
const updateProductQty = (data) => { const { catid, prodid } = data; setProductData(prevData => { // 函数式更新确保基于最新状态操作 return prevData.map(category => { if (category.catid !== catid) { return category; } // 复制分类对象,更新其产品数组 return { ...category, product: category.product.map(product => { if (product.id !== prodid) { return product; } // 复制产品对象并更新qty return { ...product, qty: product.qty + 1 // 可改为固定值或其他逻辑,比如直接设为2 }; }) }; }); }); };
代码说明
- 函数式状态更新:使用
setProductData(prevData => ...)避免闭包导致的旧状态问题,确保每次更新都基于最新的状态值 - 不可变更新:逐层复制原对象,仅修改目标属性,保证其他数据不受影响
- 通用匹配逻辑:通过遍历产品数组匹配
id,不再依赖硬编码索引,适配任意数量的产品和分类
内容的提问来源于stack exchange,提问作者Krish Varma
相关产品推荐
相关产品推荐

