admin管理员组文章数量:1296248
I have this problem.
With interface:
export interface IDevice {
id: string,
selected: boolean
}
creating instance by:
let newDevice: IDevice = {
id: uuid4(),
selected: false,
} as IDevice;
It gets added to array in recoil state, and in React used in a function where array has been retrieved with useRecoilState().
const [leftList, setLeftList] = React.useState<IDevice[]>([]);
Now it is being used in a handler for selecting the devices on a list control, here the error occurs:
...
leftList.map((item: IDevice) => {
if (item.id === event.dataItem.id) {
item.selected = !item.selected;
}
return item;
})
...
And I get the error: Cannot assign to read only property 'selected' of object '#'
Even cloning the array first by [...leftList] does not help.
I'm lost:-) Hope someone can spread light on this?
I have this problem.
With interface:
export interface IDevice {
id: string,
selected: boolean
}
creating instance by:
let newDevice: IDevice = {
id: uuid4(),
selected: false,
} as IDevice;
It gets added to array in recoil state, and in React used in a function where array has been retrieved with useRecoilState().
const [leftList, setLeftList] = React.useState<IDevice[]>([]);
Now it is being used in a handler for selecting the devices on a list control, here the error occurs:
...
leftList.map((item: IDevice) => {
if (item.id === event.dataItem.id) {
item.selected = !item.selected;
}
return item;
})
...
And I get the error: Cannot assign to read only property 'selected' of object '#'
Even cloning the array first by [...leftList] does not help.
I'm lost:-) Hope someone can spread light on this?
Share Improve this question asked Feb 9, 2021 at 9:54 Peter Stjernholm MeldgaardPeter Stjernholm Meldgaard 2501 gold badge4 silver badges17 bronze badges 1-
1
State shouldn't be modified directly, which is what TS is trying to tell you by making your object read-only, create a new object and return that instead
return {...item, selected: item.id === event.dataItem.id ? !item.selected : item.selected}
. Cloning the array using the spread syntax will only do a shallow copy, and won't do a deep-copy of the objects within it – Nick Parsons Commented Feb 9, 2021 at 9:59
1 Answer
Reset to default 7State shouldn't be modified directly, which is what you're currently doing now in your .map()
method by updating the objects. TS is trying to tell you not to do this by making your objects read-only.
Instead, you can create a new object with all the properties from item
(done using the spread syntax ...), along with a new overwritting property selected
, which will use the negated version of the item's currently selected item if the id matches the event's data item id, or it'll keep the original selected value:
leftList.map((item: IDevice) => ({
...item,
selected: item.id === event.dataItem.id ? !item.selected : item.selected
}))
Cloning the array using the spread syntax ([...leftList]
) will only do a shallow copy, and won't do a deep-copy of the objects within it, as a result, modifying the object references within .map()
is still modifying the original state.
Or, instead of spreading the item
object and creating a new object each time (which can hinder performance a little as pointed out by @3limin4t0r), you can instead only return a newly created object when you want to modify the selected
property:
leftList.map((item: IDevice) => {
if (item.id !== event.dataItem.id) return item;
return {...item, selected: !item.selected};
});
本文标签: javascriptCannot assign to read only property 39property39 of object 39ltObjectgt39Stack Overflow
版权声明:本文标题:javascript - Cannot assign to read only property 'property' of object '#<Object>' 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741619635a2388732.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论