React状态随赋值变量变更问题求助:如何修改变量不影响原状态
解决React中修改拷贝对象导致原state改变的问题
嘿,这个问题我太熟了——这是JavaScript引用类型的经典陷阱!咱们先搞明白为啥会出现这种情况:
你定义的testState是一个对象,而对象在JS里是引用类型。当你执行a = this.state.testState的时候,并没有把这个对象复制一份给a,只是让变量a指向了内存中同一个对象的地址。所以你修改a.testValue的时候,本质上就是在修改原state里的那个对象,控制台自然会输出修改后的值。
要解决这个问题,核心就是创建原对象的副本,而不是直接引用它。根据你的对象结构,有几种不同的方案:
1. 浅拷贝(适合单层结构的对象)
如果你的testState只有一层属性(像例子里这样没有嵌套对象/数组),用这两种方法就足够了:
方法一:扩展运算符(推荐,语法更简洁)
testFn = () => { let a = {...this.state.testState}; // 用扩展运算符创建对象副本 a.testValue = "Debugging is awesome"; console.log(this.state.testState); // 现在输出 {testValue: "Test State"} }
方法二:Object.assign()
testFn = () => { let a = Object.assign({}, this.state.testState); // 把原对象属性拷贝到空对象里 a.testValue = "Debugging is awesome"; console.log(this.state.testState); // 原state不受影响 }
2. 深拷贝(适合有嵌套结构的对象)
如果你的testState里还有嵌套的对象或者数组,浅拷贝就不够用了——因为浅拷贝只会复制第一层属性,嵌套的对象还是引用关系。这时候可以用这些方法:
方法一:JSON序列化/反序列化
这是最常用的无依赖深拷贝方式:
testFn = () => { let a = JSON.parse(JSON.stringify(this.state.testState)); // 先转成JSON字符串再转回来,实现深拷贝 a.testValue = "Debugging is awesome"; console.log(this.state.testState); // 原state完全不受影响 }
⚠️ 注意:这个方法有局限性,不能处理包含函数、Symbol、循环引用的对象,如果你对象里有这些类型的数据,就不能用这个方法。
方法二:第三方库(比如Lodash的cloneDeep)
如果你的项目已经引入了Lodash,可以直接用它的深拷贝方法:
import _ from 'lodash'; testFn = () => { let a = _.cloneDeep(this.state.testState); a.testValue = "Debugging is awesome"; console.log(this.state.testState); }
最后再提一句:在React开发里,永远不要直接修改this.state的属性,哪怕是临时修改,最好都通过创建副本的方式来操作,避免意外污染原state哦!
内容的提问来源于stack exchange,提问作者Muhzin
相关产品推荐
相关产品推荐

