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)
      };
    });
  }