Reputation: 504
I am learning Redux. However, I understood that the reducer is a function that receives the current state and an action object, then decides how to update the state, make a copy of it, update the deep copied state and finally returns the new state.
So, the code below is a typical example of it:
const initialState = { value: 0 }
function counterReducer(state = initialState, action) { // Check to see if the reducer cares about this action if (action.type === 'counter/increment') {
// If so, make a copy of `state`
return {
...state,
// and update the copy with the new value
value: state.value + 1
} } // otherwise return the existing state unchanged return state }
However, you realize that it is using the spread operator to make a copy of the state. The spread operator make just a shallow copy of it. So, it means that the state should not be multidimensional object?
Because, as I know, the spread operator does not work with multi-dimensional arrays or objects. If it is multi-dimensional the values are copied by referenced instead of by value. It is the reason that if you really want to make a deep copy of an object or an array you could use Lodash library, structuredClone or even JSON.parse(JSON.stringify("your object/array" here).
So, does someone know if the store is just one level object store in Redux? Then in this case it works without any problem using spread operator. Or it is a spread operator representation that intern the Redux Library makes really a deep clone of it?
Thank you very much in advance!
Cheers, Turtles
Upvotes: 1
Views: 915
Reputation: 504
In fact, the answer is that if you have an state multi-dimension, you will have to write your reducer like this to work:
function handwrittenReducer(state, action) {
return {
...state,
first: {
...state.first,
second: {
...state.first.second,
[action.someId]: {
...state.first.second[action.someId],
fourth: action.someValue
}
}
}
}
}
However, nowadays we use the createSlice function of the Redux Toolkit's. So, the createSlice uses a library called Immer inside.
"Immer uses a special JS tool called a Proxy to wrap the data you provide, and lets you write code that "mutates" that wrapped data. But, Immer track all the changes you've tried to make, and then uses that list of changes to return a safely immutably updated value, as if you'd written all the immutable update logic by hand."
So, the code above can be simplified to:
function reducerWithImmer(state, action) {
state.first.second[action.someId].fourth = action.someValue
}
Just take in mind:
"You can only write "mutatin" logic in Redux Tookit's createSlice and createReducer because they use Immer inside! If you write mutating logic in reducers without Immer, it will mutate the state and cause bugs!"
Cheers, Turtles
Upvotes: 1