React中嵌套数组内嵌套对象更新报错及实现需求问询
解决React嵌套数组更新报错&实现指定元素更新
咱们一步步拆解你的问题,既要解决控制台的报错,也要实现你想要的嵌套对象更新功能。
一、报错原因分析
你点击Save按钮后出现的Uncaught TypeError: this.props.product.colors.map is not a function,核心问题是**colors被替换成了单个对象,不再是数组**:
- 在
Item的save函数里,你只把单个更新对象p传给了update; - 而
App的update函数直接将目标产品的colors替换成了这个单个对象:Object.assign({}, prevState.products[selectProductIndex], {colors: item}),
原本colors是数组,现在变成了单个对象,后续Items组件调用map方法自然会报错。
另外,你的初始state里第二个产品的colors数组存在语法错误,这会导致初始渲染就出问题:
// 错误写法,第二个元素的对象格式完全混乱 colors: [{a:'black', desc: 'g', date: '12-12-2019'}, {a: 'white', {a:'black', desc: 'grtrt', date: '12-12-2119'}, }, {a:'gray', desc:'', date: '01-01-2000'}],
得改成标准的键值对对象结构,比如:
// 修正后 colors: [{a:'black', desc: 'g', date: '12-12-2019'}, {a: 'white', desc: 'white-desc', date: '12-12-2119'}, {a:'gray', desc:'', date: '01-01-2000'}],
二、正确实现嵌套数组元素更新
要实现更新products数组中对应产品的colors数组内第二个对象,我们需要传递「要修改的元素索引」和「更新后的对象」,再在update函数里精准修改数组指定位置的元素。
第一步:修改Item组件的save函数
把当前Item对应的colors索引(this.props.index)和更新对象一起传给update,让update知道要修改哪个元素:
class Item extends Component { save = () => { const updatedColor = { a:'violet', desc: 'gt', date: '12-12-1980' } // 传递索引和新对象 this.props.update(this.props.index, updatedColor) } render() { return ( <div> <button onClick={this.save}>Save</button> </div> ) } }
第二步:修改App组件的update函数
遵循React的不可变状态原则,先复制原数组再修改指定元素,避免直接修改state:
update = (colorIndex, updatedColor) => { const {selectProductIndex} = this.state; this.setState(prevState => { // 获取要修改的目标产品 const targetProduct = prevState.products[selectProductIndex]; // 复制原colors数组,避免直接修改原state const newColors = [...targetProduct.colors]; // 替换指定索引的元素 newColors[colorIndex] = updatedColor; // 生成新的products数组返回 return { products: [ ...prevState.products.slice(0, selectProductIndex), // 复制原产品并替换colors为新数组 {...targetProduct, colors: newColors}, ...prevState.products.slice(selectProductIndex + 1) ] }; }); }
第三步:修正初始state的语法错误
把之前写错的第二个产品的colors数组修正为标准格式,确保初始渲染正常。
三、验证效果
现在点击Save按钮后:
Item组件将当前元素的索引(1,对应colors数组第二个元素)和新对象传给update;update函数复制原colors数组、修改指定元素,再更新到products数组中;Items组件接收到的colors仍然是数组,能正常调用map方法,不会再报错;- 最终products数组中第一个产品的colors数组第二个元素,会从
{a: 'purple', desc: 'grt', date: '12-10-2019'}更新为{a: 'violet', desc: 'gt', date: '12-12-1980'},完全符合你的预期。
内容的提问来源于stack exchange,提问作者Umbro
相关产品推荐
相关产品推荐

