Error: Attempting to set key on an object that is immutable and has been frozen
Error: Attempting to set key on an object that is immutable and has been frozen
我很难找到与此错误相关的问题,显然这意味着我正在尝试更新不可变对象。奇怪的是,我之前使用过这个实现没有任何障碍,这就是为什么我发现这种行为如此令人困惑。
下面是我正在使用的方法,它只是改变数组的对象,改变 属性 和 returns 的更新状态。正如所引用的 here,使用 prevState
似乎是绕过不变性的最佳方式。
onCheck = (id) => {
this.setState((prevState) => {
prevState.options[id].checked = !prevState.options[id].checked;
return {
options: prevState.options,
dataSource: prevState.cloneWithRows(prevState.options)
};
});
}
我也尝试了多种复制 prevState 的变体,但它仍然给我同样的不变性错误。它似乎仍然引用而不是重复 prevState
.
onCheck = (id) => {
this.setState((prevState) => {
let options = [...prevState.options];
options[id].checked = !options[id].checked;
return {
options: options,
dataSource: this.state.cloneWithRows(options)
};
});
}
在您的问题中,您承认您正在改变状态,但您不能这样做。解决此问题的方法是先克隆 prevState.options,然后再摆弄它。
例如
var options = Object.assign({}, prevState.options)
options[id].checked
return {
options,
...
正如您的 reference 所指出的,您不应该像
那样直接改变您的数据
prevState.options[id].checked = !prevState.options[id].checked;
在您的 link 中,他们 return 通过 concat
或 "spread syntax" (...) 的新数组。所以我建议你先复制你的prevState
然后改变它
let state = [...prevState.options];
state[id].checked = !state[id].checked;
...
我最终找到了解决方案,看来我不仅需要复制数组,还需要复制数组的每个元素。由于数组的各个元素/对象仍然不可变/冻结。
onCheck = (id) => {
this.setState((prevState) => {
const newOptions = prevState.options.map((option, index) => {
let copyOption = {...option};
if (id == index) {
copyOption.checked = !copyOption.checked;
}
return copyOption;
});
return {
options: newOptions,
dataSource: this.state.dataSource.cloneWithRows(newOptions)
};
});
}
我很难找到与此错误相关的问题,显然这意味着我正在尝试更新不可变对象。奇怪的是,我之前使用过这个实现没有任何障碍,这就是为什么我发现这种行为如此令人困惑。
下面是我正在使用的方法,它只是改变数组的对象,改变 属性 和 returns 的更新状态。正如所引用的 here,使用 prevState
似乎是绕过不变性的最佳方式。
onCheck = (id) => {
this.setState((prevState) => {
prevState.options[id].checked = !prevState.options[id].checked;
return {
options: prevState.options,
dataSource: prevState.cloneWithRows(prevState.options)
};
});
}
我也尝试了多种复制 prevState 的变体,但它仍然给我同样的不变性错误。它似乎仍然引用而不是重复 prevState
.
onCheck = (id) => {
this.setState((prevState) => {
let options = [...prevState.options];
options[id].checked = !options[id].checked;
return {
options: options,
dataSource: this.state.cloneWithRows(options)
};
});
}
在您的问题中,您承认您正在改变状态,但您不能这样做。解决此问题的方法是先克隆 prevState.options,然后再摆弄它。
例如
var options = Object.assign({}, prevState.options)
options[id].checked
return {
options,
...
正如您的 reference 所指出的,您不应该像
那样直接改变您的数据prevState.options[id].checked = !prevState.options[id].checked;
在您的 link 中,他们 return 通过 concat
或 "spread syntax" (...) 的新数组。所以我建议你先复制你的prevState
然后改变它
let state = [...prevState.options];
state[id].checked = !state[id].checked;
...
我最终找到了解决方案,看来我不仅需要复制数组,还需要复制数组的每个元素。由于数组的各个元素/对象仍然不可变/冻结。
onCheck = (id) => {
this.setState((prevState) => {
const newOptions = prevState.options.map((option, index) => {
let copyOption = {...option};
if (id == index) {
copyOption.checked = !copyOption.checked;
}
return copyOption;
});
return {
options: newOptions,
dataSource: this.state.dataSource.cloneWithRows(newOptions)
};
});
}