Angular 为什么它被认为是NgRx中存储值的直接修改
关于代码片段的信息:state有一个切片Angular 为什么它被认为是NgRx中存储值的直接修改,angular,ngrx,ngrx-store,Angular,Ngrx,Ngrx Store,关于代码片段的信息:state有一个切片educationList,它是各种教育(学士、硕士、博士)的数组。educationList数组中的每个项目都包含另一个数组description,其中包含项目、论文等的信息 以下是用于删除description数组中某个项的代码段: case Actions.DELETE_ROLE: { let updatedEducationList = [...state.educationList]; const targetIndex
educationList
,它是各种教育(学士、硕士、博士)的数组。educationList
数组中的每个项目都包含另一个数组description
,其中包含项目、论文等的信息
以下是用于删除description
数组中某个项的代码段:
case Actions.DELETE_ROLE: {
let updatedEducationList = [...state.educationList];
const targetIndex = updatedEducationList.findIndex((educationItem) => {
return educationItem.id === action.payload.educationId;
});
let oldDescription = updatedEducationList[targetIndex].description;
let newDescription = oldDescription.filter((item, index) => index !== action.payload.roleIndex);
updatedEducationList[targetIndex] = { ...updatedEducationList[targetIndex], description: newDescription };
return { ...state, educationList: updatedEducationList };
}
如果代码段中有以下行
updatedEducationList[targetIndex] = { ...updatedEducationList[targetIndex], description: newDescription }
被替换为
updatedEducationList[targetIndex].description = newDescription; //Edited this line
发生错误。错误如下
core.js:6014 ERROR TypeError: Cannot assign to read only property 'description' of object '[object Object]'
at educationListReducer (education-list.reducer.ts:110)
at combination (store.js:303)
at store.js:1213
at store.js:383
at ScanSubscriber.reduceState [as accumulator] (store.js:688)
at ScanSubscriber._tryNext (scan.js:49)
at ScanSubscriber._next (scan.js:42)
at ScanSubscriber.next (Subscriber.js:49)
at WithLatestFromSubscriber._next (withLatestFrom.js:57)
at WithLatestFromSubscriber.next (Subscriber.js:49)
但我想我已经复制了第1行中的状态本身。
let updatedEducationList = [...state.educationList];
我错过了什么 让updateeducationlist=[…state.educationList];
//现在updatedEducationList是一个新数组
//但它的每个元素都指向当前状态中的相关值。
//因为它不是深度克隆。
const targetIndex=updatedEducationList.findIndex((educationItem)=>{
返回educationItem.id==action.payload.educationId;
});
//现在,如果您选中state.educationList[targetIndex]==updatedEducationList[targetIndex],它将为true。
//尽管updatedEducationList==state,但educationList为false。
让oldDescription=updatedEducationList[targetIndex].description;
//现在它指向当前状态。
让newDescription=oldscription.filter((项目,索引)=>index!==action.payload.roleIndex);
//指向当前状态项的新指针数组。
updatedEducationList[targetIndex]。description=newDescription;
//错误,因为updatedEducationList[targetIndex]仍然指向当前状态。描述也是如此。
updatedEducationList[targetIndex]={…updatedEducationList[targetIndex],description:newDescription};
//对,因为它创建的新对象不再指向当前状态。只显示其键的值。
返回{…状态,educationList:updatedEducationList};
回答
对于包含其他对象或数组的对象和数组,复制这些对象需要深度复制。否则,对嵌套引用所做的更改将更改嵌套在原始对象或数组中的数据。在这种情况下,
description
是一个嵌套对象,因此在浅拷贝之后,它仍然指向内存中与原始状态相同的地址。为了便于阅读,编辑了这个问题。description是长度为1或2的数组。您的问题是为什么不能直接更改updateeducationlist[targetIndex]。description=newDescription
?因为代码段中的代码看起来是正确的。是的。因为,我认为我不是直接修改状态,而是通过return{…state,educationList:updateeducationlist}返回状态代码>啊,我明白了。事实上是的。我会更新答案。1秒。完成,在每一行下面你可以找到它的作用的解释。