- you need to have side effects
- you need to read from store to decide what to do
- you need to dispatch more than one action
- action produced by action creator needs to contain all the data reducer can need to shape the components state
- should not have any side effects
- should not read global application state
- should not manipulate data structures passed with the action, it should only pick the right data and merge it into state
I stumbled upon this post because I found myself having all reducers responding with,
it felt fishy, I'd put it different words to see if I understood well why this is an anti-pattern
and to explain how I ( and I think many other users too) ended falling in the anti-pattern.
After reading this posts I understood that because
one
action
can affect one or manyreducers
its payload should be "reducer agnostic",the reducer should be picking the properties it needs from the payload so that the reducer keeps
the ownership of the store shape.
This is much more maintainable because if you ever have to change the shape of the store,
there is only one place to change it, you go to the particular reducer and is just one change.
But If you do
...action.payload
in the reducer, you'll have to check all the actions that you are reacting to,change those, and then also check if there are other reducers reacting and adjust those too,
definitely much harder to maintain.
So why I ended doing
return {...state, ...action.payload}
?It started with a normal reducer like this ...
Because all keys match and
action.payload
looks redudant, and because we havees6
then I go ...Which still kind of OK because it respects the patter, I'm cherry picking the properties from the payload,
but then you (or a colleague) come back, see that code, and realize the action just returns those 3 props,
and because we all love
...spreadOperator
then I end up withAnd now I learnt this ☝️ is an anti-pattern
Thank you!