无法分配给对象“#<Object>”的只读 属性 'property'

Cannot assign to read only property 'property' of object '#<Object>'

我有这个问题。

带接口:

export interface IDevice {
  id: string,
  selected: boolean
}

通过以下方式创建实例:

let newDevice: IDevice = {
  id: uuid4(),
  selected: false,
} as IDevice;

它以反冲状态添加到数组中,并在 React 中用在函数中,其中数组已通过 useRecoilState() 检索。 const [leftList, setLeftList] = React.useState<IDevice[]>([]);

现在它被用于选择列表控件上的设备的处理程序中,这里出现错误:

...
leftList.map((item: IDevice) => {     
      if (item.id === event.dataItem.id) {
        item.selected = !item.selected;
      }
      return item;
    })
...

我收到错误消息:无法分配给对象“#”

的只读 属性 'selected'

即使先通过 [...leftList] 克隆数组也无济于事。

我迷路了:-)希望有人能对此有所了解?

不应直接修改状态,这就是您目前在 .map() 方法中通过更新对象所做的事情。 TS 试图通过将您的对象设为只读来告诉您不要这样做。

相反,您可以使用 item 中的所有属性创建一个新对象(使用 spread syntax ... 完成),以及新的覆盖 属性 selected,如果 id 与事件的数据项 id 匹配,它将使用项目当前选定项目的否定版本,否则它将保留原始选定值:

leftList.map((item: IDevice) => ({
  ...item, 
  selected: item.id === event.dataItem.id ? !item.selected : item.selected
}))

使用扩展语法([...leftList])克隆数组只会做一个浅拷贝,不会对其中的对象进行深拷贝,因此,修改其中的对象引用.map()还在修改原状态

或者,不是传播 item 对象并每次都创建一个新对象(正如 @3limin4t0r 所指出的,这可能会稍微影响性能),您可以只 return 新建对象时要修改 selected 属性:

leftList.map((item: IDevice) => {     
  if (item.id !== event.dataItem.id) return item;
  return {...item, selected: !item.selected};
});