使用展开运算符更新数组内对象不生效的原因及解决方法
原因说明
你的判断完全正确。Array.find() 返回的是数组中匹配项的引用,你之前逐行写 equipment.countryId = xxx 时,是直接在操作数组内存里的那个原对象,所以修改会同步反映到数组上。
但你写的 equipment = { ...equipment, ...this.currentItem } 逻辑是:先创建一个全新的对象,把旧对象和新对象的属性都展开拷贝进去,再把这个新对象赋值给 equipment 这个局部变量。这个操作只是改变了equipment变量本身的指向,从「指向数组里的原对象」变成了「指向你新创建的对象」,数组里存的还是原来的旧对象引用,自然不会有任何更新。
实现方式
直接修改原对象(匹配你原有代码的逻辑)
用原生的 Object.assign 即可,不需要逐行给每个属性写赋值语句,它会把后续所有参数对象的可枚举属性,全量合并到第一个参数的目标对象上,直接修改原对象:
const equipment = this.equipments.find((e) => e.id === this.currentItem.id); // 把currentItem的所有属性合并到数组内的原对象上 Object.assign(equipment, this.currentItem);
如果
currentItem里带有id这类不需要覆盖的标识属性,可以提前从currentItem里剔除对应字段再合并,避免误改唯一标识。
不可变更新(适配React/Vue3等不可变状态场景)
如果你使用的前端框架要求不能直接修改原状态(避免响应式更新异常),可以直接生成新数组替换旧值,不需要单独做find操作:
this.equipments = this.equipments.map(item => { return item.id === this.currentItem.id ? { ...item, ...this.currentItem } : item })
这种写法不会改动原数组和原对象,符合不可变数据的开发规范,触发视图更新的逻辑会更可靠。
内容的提问来源于stack exchange,提问作者Pawan Nogariya
相关产品推荐
相关产品推荐

