最近在写react,今天遇到了一个问题,由于reducer不能直接操作state,因此在操作之前需要进行拷贝,按照常规的思路将state赋值给一个新const,这个时候坑就来了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
setClientStatus(state, action){ // 拷贝一份出来 reducer是不能够直接去修改state的值的 const newList =state.data.list; // 然后操作了这个拷贝出来的newList发现state也跟着变了 JSON.parse(action.payload).forEach((val)=>{ newList.forEach((listVal)=>{ if(listVal.client_id === val.clientId){ console.log(listVal); listVal.online = val.online // value.online = val.online; } }); }); return { ...state, }; } |
直接这样return(并没有将新的数据放入return中),会发现state改变了,新的数据进来了,这个时候就意识到了拷贝没有成功,操作新的const newList的时候影响了原来state的数据,由于state的数据是不能够直接修改的,因此这样肯定是有问题的,出现这个问题的原因是:
在js中:
- 基本类型值是存储在栈中的简单数据段,也就是说,他们的值直接存储在变量访问的位置。
- 堆是存放数据的基于散列算法的数据结构,在javascript中,引用值是存放在堆中的。
所以问题就是直接这样const赋值,指向的是同一个堆中的空间,导致操作新的const的时候旧的也跟着被操作了。
因此 要使用
深拷贝!
1 |
const newState = JSON.parse(JSON.stringify(state)); |
看来还是需要打好js的基础啊