为何React组件中map()方法未调用setState却修改了state?
问题原因与修复方案
原因分析
你遇到的问题核心是引用类型的数据特性:map()方法确实返回了一个新数组,但数组里的每个对象元素,依然是原state.colors中对象的引用。当你在map回调里直接执行e.color = ...时,本质是在修改原state里的对象内容——因为对象是引用类型,操作的是内存中的同一个对象,所以哪怕没调用setState,state里的数据已经被改动了。
修复代码
要解决这个问题,需要在修改对象时创建原对象的拷贝,避免直接修改原state里的引用。可以用对象展开运算符实现浅拷贝:
class Color1 extends Component { state = { colors: [ { key: 1, color: 'green' }, { key: 2, color: 'red' }, { key: 3, color: 'red' }, { key: 4, color: 'green' }, ], }; changeColor = color => { console.log(this.state.colors); const pehli = this.state.colors.map(e => { if (e.key === color.key) { // 创建原对象的浅拷贝,修改新对象的color属性 return { ...e, color: e.color === 'green' ? 'red' : 'green' }; } else { return e; } }); console.log(this.state.colors); // 现在原state不会被修改了 // 之后可以安全调用setState更新状态 // this.setState({ colors: pehli }); }; }
补充说明
- 这里用的是浅拷贝,如果你的对象层级更深(比如嵌套对象),需要用深拷贝(比如
JSON.parse(JSON.stringify(e))),但当前场景下浅拷贝足够。 - React要求state是不可变的,直接修改state会导致组件无法正确触发重新渲染,也会引发难以追踪的bug,所以一定要遵循“不直接修改state,通过拷贝后修改再更新”的原则。
内容的提问来源于stack exchange,提问作者InkCode
相关产品推荐
相关产品推荐

