关于浅拷贝与赋值
来源:7-10 setState为何使用不可变值
陌上兮月
2021-01-06
老师,如果state是引用类型,我们可以用...
来做浅拷贝,然而对于深层嵌套的对象来讲,浅拷贝的对象里存放的仍然是指针。也就是说,通过一个浅拷贝的对象去改深层对象的属性,实际上改的是堆内存中的同一个地址。
constructor(props) {
super(props);
this.state = {
count: 0,
obj: {name: 'zhangsan'},
}
}
increase = () => {
const shallowCopy = { ...this.state };
setTimeout(() => {
shallowCopy.obj.name = 'lisi';
console.log(this.state); // 其实这里state.obj.name已经变为lisi了
this.setState(shallowCopy);
})
}
又或者,甚至不做浅拷贝,直接换指针,也没报错。
increase = () => {
const anotherPointer = this.state;
setTimeout(() => {
anotherPointer.obj.name = 'lisi';
console.log(this.state); // 这里state.obj.name也已经变为lisi了
this.setState(anotherPointer);
})
}
所以,不可变值对于嵌套多的引用类型来说,是不是只要换个指针重新赋值就行了?(甚至不需要做浅拷贝)。
毕竟,一个嵌套多层的对象,更改了比如info.basic.name
这样一个深层属性,应该不需要把整个info
对象深拷贝一遍再替换原来的吧?
看起来只需要换个指针就能欺骗react了。
写回答
2回答
-
你这个场景决定的,其实不用你的“浅拷贝或者换指针”。
你直接取出 state 即 const state1 = this.state
然后 state1.obj.name = 'lisi'
最后去 setState(state1)
这样做也是正常的,你可以试一下。
-------
因为你的场景中,并没有用 PureComponent 或者做 SCU 优化,所以每次 setState 都会无条件重新渲染。
所以,无论你怎么折腾,它都是正常的。
00 -
双越
2021-01-06
你不是要“欺骗”React ,你是要“欺骗”js 引擎。
因为深拷贝、浅拷贝这些,不是 React 独创的,它本身就是 js 的逻辑。
这一点你要搞明白。
032021-01-06
相似问题