'discompose javascript react state with three dots, but why we are specifying state and state's attribute separately
I am a beginner in react, and javascript in general. And rencently I been following a Youtube tutorial. In the tutorial, I saw the folling code:
const reducer = (state, action) => {
console.log(action)
switch (action.type) {
case 'ADD_TO_BASKET':
// keep the state to be whatever it is,
// and the basket is whatever it currently is plus the item passed inside.
return {
...state,
basket: [...state.basket, action.item],
};
case 'REMOVE_FROM_BASKET':
const index = state.basket.findIndex(
(basketItem) => basketItem.id === action.id
);
let newBasket = [...state.basket];
if (index >= 0) {
newBasket.splice(index, 1);
} else {
console.warn(
`Cant remove product (id: ${action.id}) as its not in the basket!`
)
}
return {
...state,
basket: newBasket
}
default:
return state;
}
I think I understand what the code is doing at a high level, such that this specifies how the reducer function is handling different requests based on the action's type.
The part that I am confusing is, from what I understand, the basket is one attribute of the state, then why in the line
return {
...state,
basket: newBasket
}
it's returning the basket alongside with the state, why couldn't it be something like
return { state.basket : newBasket }
Thanks for reading my question this far, much appreciate.
Solution 1:[1]
The syntax in question is returning a shallow clone of the entire state
object, and overriding state.basket
with a value of newBasket
.
return {
...state,
basket: newBasket
}
For example:
const state = {
basket: [],
total: 0,
user: null,
};
const stateClone = {
...state,
basket: ['apple']
};
stateClone
is now { basket: ['apple'], total: 0, user: null }
- AND it's a new object in memory.
The clone is necessary in order for the reducer to work properly, since reducers depend on immutable state. The mutable way to update state.basket
would be:
state.basket = newBasket;
return state;
However this mutates the original state
object, updating the reference in memory rather than creating a copy. This will cause the reducer to work incorrectly (e.g. it won't detect that the state has changed).
Here are the MDN docs on the spread operator when cloning an object: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#spread_in_object_literals
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |