The redux guide states:
We don't mutate the state. We create a copy with Object.assign(). Object.assign(state, { visibilityFilter: action.filter }) is also wrong: it will mutate the first argument. You must supply an empty object as the first parameter. You can also enable the object spread operator proposal to write { ...state, ...newState } instead.
I happened to catch myself writing the following snippet of working code:
[actions.setSelection](state, {payload}) {
state[payload.key] = payload.value;
return state;
},
I had a bad vibe about it, and revisited the guide for wisdom. I have since rewritten it as this:
[actions.setSelection](state, {payload}) {
const result = Object.assign({}, state);
result[payload.key] = payload.value;
return result;
},
I am fairly sure I have offended the commandment noted above elsewhere in my code. What kind of consequence am I looking at for not tracking them down with diligence?
(Note: The reducer syntax above is via redux-actions. It would otherwise be the block of code in a reducer fn switch/case.)
In Redux, our reducers are never allowed to mutate the original / current state values! // ❌ Illegal - by default, this will mutate the state! There are several reasons why you must not mutate state in Redux: It causes bugs, such as the UI not updating properly to show the latest values
Note that each of these reducers is managing its own part of the global state. The state parameter is different for every reducer, and corresponds to the part of the state it manages. This allows us to split up our logic based on features and slices of state, to keep things maintainable.
"Mutating state in React is an anti-pattern". Most of us who use React know this and grudging accept this. But there are serious consequence to not making your React/Redux code immutable. A codebase that I was working on had a weird bug. The component I was making relied on a redux state object.
Now that we know what our state structure and our actions look like, it's time to write our first reducer. Reducers are functions that take the current state and an action as arguments, and return a new state result. In other words, (state, action) => newState.
Mutating state is an anti-pattern in React. React uses a rendering engine which depends on the fact that state changes are observable. This observation is made by comparing previous state with next state. It will alter a virtual dom with the differences and write changed elements back to the dom.
When you alter the internal state, React does not know what's changed, and even worse; it's notion of the current state is incorrect. So the dom and virtual dom will become out of sync.
Redux uses the same idea to update it's store; an action can be observed by reducers which calculate the next state of the store. Changes are emitted and for example consumed by react-redux connect
.
So in short: never ever, mutate state. Instead of Object.assign you can use the stage-3 spread syntax:
{...previousState,...changes}
Also please note, this is true for arrays as well!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With