React子组件修改props时意外篡改父组件state问题求助
问题根源
- JavaScript 中数组和普通对象均为引用传递,执行
x = p.p赋值时并未生成新的数组副本,x 与父组件 state 中的 portfolio 指向同一块内存地址,修改 x 内部的对象属性会直接变更原 state 数据 - 浏览器控制台对引用类型的打印为懒求值逻辑,点击展开打印内容时才会读取当前内存中的最新值,因此即使
console.log写在修改操作之前,最终展示的也是修改后的数据
解决方案
核心逻辑是提交 Firestore 前,对要操作的数据做拷贝,在副本上做字段修改,完全不触碰原始 props 数据,以下是三种适配不同场景的实现方案:
方案1:浅拷贝数组+单层对象拷贝(适配你的当前场景,性能最优)
你的持仓项均为单层基础属性,只需拷贝数组和第一层对象即可脱离原引用:
const makeDeal = () => { // 生成完全独立的副本 const submitData = p.p.map(item => ({ ...item })); // 在副本上删除不需要提交的字段 submitData.forEach(item => { delete item.price; delete item.name; }); // 提交 submitData 到 Firestore 即可 }
方案2:全量深拷贝(适配持仓项含多层嵌套结构的场景)
如果持仓对象包含嵌套的数组/对象,可以用浏览器原生 structuredClone API 做全量深拷贝:
const makeDeal = () => { const submitData = structuredClone(p.p); submitData.forEach(item => { delete item.price; delete item.name; }); // 后续提交逻辑 }
方案3:直接过滤字段生成提交数据(最稳妥)
无需做删除操作,生成提交数据时直接筛选需要存入数据库的字段,避免临时字段遗漏删除:
const makeDeal = () => { // 示例仅保留需要存入数据库的 id、持仓数量、成本三个字段,可按需调整 const submitData = p.p.map(item => ({ id: item.id, count: item.count, cost: item.cost })); // 直接提交即可 }
内容的提问来源于stack exchange,提问作者xoma_star
相关产品推荐
相关产品推荐

