How to Handle Redux Reducers in an Immutable and Declarative Way
We’ve all written a reducer in our Redux code that has a thousand million spread operators. We’re glad it works, but we feel bad about writing because of its verbosity.
I’m going to borrow an example from this article by Chidi Orji on Smashing Magazine, to showcase what type of reducer I’m talking about, in case you’re lucky enough to never have had the chance to encounter one of these monsters out in the wild:
const updateReducer = (state = initState, action) => {
switch (action.type) {
case 'ADD_PACKAGE':
return {
...state,
packages: [...state.packages, action.package],
};
case 'UPDATE_INSTALLED':
return {
...state,
packages: state.packages.map(pack =>
pack.name === action.name
? { ...pack, installed: action.installed }
: pack
),
};
default:
return state;
}
};
This one is not that bad to be honest: believe me, I’ve seen and written worse!
So what is the problem here, exactly? Well, if we want to update a property of an object that is deeply nested in our state tree, there’s a lot of copying and spreading we have to do, in order to clone the current state and return new state. Remember: reducers are not supposed to perform side effects as…