Javascript TypeError:无法分配到react JS中的只读属性

Javascript TypeError:无法分配到react JS中的只读属性,javascript,arrays,reactjs,redux,react-redux,Javascript,Arrays,Reactjs,Redux,React Redux,下面是呈现任务数组的任务组件 导出函数任务(){ const tasks=useSelector((state)=>state.tasks.taskArray); 函数handleOnDragEnd(结果){ 如果(!result.destination)返回; let items=[…tasks];//还尝试使用tasks.slice()获取深度副本 设i=result.source.index; 让方向=result.destination.index>result.source.inde

下面是呈现任务数组的任务组件


导出函数任务(){
const tasks=useSelector((state)=>state.tasks.taskArray);
函数handleOnDragEnd(结果){
如果(!result.destination)返回;
let items=[…tasks];//还尝试使用tasks.slice()获取深度副本
设i=result.source.index;
让方向=result.destination.index>result.source.index;
//方向为真意味着向右移动和交换
while(i!=result.destination.index){
如果(指示){
设tempGlobalKey=items[i].globalKey;

items[i].globalKey=items[i+1].globalKey;//当您使用Redux时,reducer的目的不是改变以前的状态,而是返回一个新修改的状态

这听起来像是一个微不足道的区别,但事实并非如此,因为之前的状态对象通常是不可变的,这取决于框架和/或流量实现

您可以通过将reducer的代码更改为此代码使其工作

减速器:{
updateOrder:(先前状态,{payload})=>{
返回{
…以前的状态,
任务阵列:有效载荷
}
},
}
编辑:

似乎您正在尝试深度克隆嵌套对象。 下面的代码

constmynewarray=[…myOldArray];
使用旧数组中的所有值在内存中创建一个新对象,并且变异新对象不会更改旧数组

有一个小警告,数组中的每个子元素都将通过引用而不是值进行克隆。 这意味着做这样的事情:

constmyoldarray=[{a:“你好”}]
常量myNewArray=[…myOldArray];
将保留对相同
{a:“hello”}
对象的引用

因此,执行
myNewArray.push(“asdf”)
不会影响
myOldArray
,但执行
myNewArray[0]。a=“再见”
也会影响
myOldArray
的第一项


这里有一篇文章有更好的解释

当您使用Redux时,reducer的目的不是改变以前的状态,而是返回一个新修改的状态

这听起来像是一个微不足道的区别,但事实并非如此,因为之前的状态对象通常是不可变的,这取决于框架和/或流量实现

您可以通过将reducer的代码更改为此代码使其工作

减速器:{
updateOrder:(先前状态,{payload})=>{
返回{
…以前的状态,
任务阵列:有效载荷
}
},
}
编辑:

似乎您正在尝试深度克隆嵌套对象。 下面的代码

constmynewarray=[…myOldArray];
使用旧数组中的所有值在内存中创建一个新对象,并且变异新对象不会更改旧数组

有一个小警告,数组中的每个子元素都将通过引用而不是值进行克隆。 这意味着做这样的事情:

constmyoldarray=[{a:“你好”}]
常量myNewArray=[…myOldArray];
将保留对相同
{a:“hello”}
对象的引用

因此,执行
myNewArray.push(“asdf”)
不会影响
myOldArray
,但执行
myNewArray[0]。a=“再见”
也会影响
myOldArray
的第一项


这里有一篇文章有更好的解释

这并不能解决我的问题,我不认为它应该解决。我提到我正在使用redux工具包,它使用immer来维护状态的不变性。我正在更新它提供的代理状态,而不是react状态。我认为问题在于
是一个肤浅的副本,所以它是给出错误。但是
[…tasks]
应该创建一个新数组,而不是一个副本。我的错是,答案大多是对我从代码中可以推断出什么的猜测。如果不知道
handleOnDragEnd()的位置/方式,就很难完全理解你在尝试做什么
函数被调用,您将传递的内容作为
结果
参数,或者在定义
dispatch
的地方,我猜是
usedpatch()
hook?我的观点是这有点难以猜测。试着制作一个小的codesandbox示例,它可能更容易传达整个场景。如果你想知道这是否是深层/浅层克隆问题,你也可以尝试
JSON.parse(JSON.stringify(nestedArray))
。数组的解构只进行了一个级别的深度。stringify然后解析有效的项。似乎
[…任务]
无法正常工作。理想情况下,在创建新数组时应断开状态绑定。Stringify和解析作为一项不错的技术工作,但仍在等待正确的答案。感谢mate很高兴你解决了它,mate,下面是一篇关于为什么你不能让它与
[…任务]一起工作的文章
。本质上,原因是数组中有对象,需要类似于
[…tasks.map((task)=>({…task}])的内容
要深入到两个级别,请为每个额外级别添加一个额外的
.map
。这并不能解决我的问题,我也不认为应该这样做。我提到我正在使用redux toolkit,它使用immer来维护状态的不变性。我正在更新它提供的代理状态,而不是react状态。我认为问题在于
是一个肤浅的副本,因此它给出了错误。但是
[…任务]
应该创建一个新的数组,而不是副本。我的错,答案主要是对我从代码中可以推断出什么的猜测。如果不知道
handleOnDragEnd()的位置/方式,就很难完全理解你在尝试做什么
函数被调用,您将传递的内容作为
结果
参数,或定义
d的位置
TypeError: Cannot assign to read only property 'globalKey' of object '#<Object>'
handleOnDragEnd
src/containers/tasks/index.js:60
  57 |     i++;
  58 | } else {
  59 |     let tempGlobalKey = items[i].globalKey;
> 60 |     items[i].globalKey = items[i - 1].globalKey;
     | ^  61 |     items[i - 1].globalKey = tempGlobalKey;
  62 |     i--;
  63 | }