3

#interestingProblem can anybody explain, please I had a problem while updating the state as in the first code block, but there was no problem when I updated the state as in the second code block as below.

I had a problem: (cannot assign to read-only property of object quantity)

const newItem = action.payload
newItem.quantity = 1
state.items = [...state.items, newItem]

I had no problem when I wrote the code like this

const newItem = action.payload
state.items = [...state.items, { ...newItem, quantity: 1 }]
Saad Saif
  • 101
  • 1
  • 2
  • 8
  • Does this answer your question? [Uncaught TypeError: Cannot assign to read only property](https://stackoverflow.com/questions/27519836/uncaught-typeerror-cannot-assign-to-read-only-property) – Vega Jun 28 '22 at 05:11

4 Answers4

5

the first approach you are mutating action.payload directly since you are not creating a copy to newItem but passing the same reference. Given action.payload is readonly you face the error:

// passing the same reference, 'newItem' points to 'action.payload'
// hence newItem is not copy
const newItem = action.payload
// here you mutate 'action.payload' since 'newItem' points to same reference
newItem.quantity = 1
state.items = [...state.items, newItem]

second approach works because you are creating a copy from action.payload not mutating it:

// here 'newItem' still points to same reference 'action.payload'
const newItem = action.payload
// but here you are spreading the values into a new object, not mutating directly
state.items = [...state.items, { ...newItem, quantity: 1 }]

instead you should create a copy first to your approach to work:

// here you create a new object from 'action.payload''action.payload'
// hence newItem contains the same values but it's a different object
const newItem = { ...action.payload }
// now you are not mutating 'action.payload', only 'newItem' that's a new object
newItem.quantity = 1
state.items = [...state.items, newItem]
buzatto
  • 9,704
  • 5
  • 24
  • 33
1

action.payload might be a readonly object. On the second code block, the spread operator passes the key-value pairs to the new object.

jrcamatog
  • 1,341
  • 5
  • 14
0

Because when doing a like **kwargs with state in React I assume, you are passing a no nested state into one that has a nested state reassinging it to a non-nested stated breaking the goal of you're code.

0

This can solve the problem

const newItem = structuredClone(action.payload)
newItem.quantity = 1
state.items = [...state.items, newItem]

JavaScript has inbuilt function to create an deep copy of any object.

const copiedObject = structuredClone(existingObject);

Also,

const copiedObject = { ...existingObject }; //This doesn't create deep copy❌

Spread operator in JavaScript doesn't create deep copy of an object