So over this module, you learned a lot about the advanced things you can do with redux especially action
creators and middleware are key things since they allow us to run async code when dispatching our actions.
Now I want to dive into advanced reducers set ups,
right now we have two reducers,
it's a bit advanced because we already split it up and use combined reducers but each reducer still has
a relatively long switch statement and even when breaking up your reducers into multiple files, you probably
still have relatively long switch case statements for each reducer, at least if it handles more than two
actions.
So cleaning up that reducer file a bit more can be an idea
and I say can be, it's not a must,
it's optional
it's a good practice I'd say
but you don't have to do it.
I want to show you some ways of cleaning up this reducer step by step though to end up with a very
clean reducer,
again what I show you is optional though.
So the first thing we can do is related to immutability,
we constantly update an object here in the end whenever we return a new state,
what we do is we just return an updated object, we return an object which copies the properties of the
old state and then replaces one of the properties.
Now obviously, we can absolutely do it like this but we could create utility functions for that and the
same for updating
arrays, this would then allow us to call this utility function and save some code here,
how could this look like?
Well let me show you.
For that, I'll create a new file which I'll name utility and I'll store that in the store folder,
you could store it in the reducers folder but I don't want to have this file look like it was a reducer
and you could store it in some other folder but I'll use it in redux only,
so for me the store folder sounds great.
There I'll create a function with the ES6 arrow function style,
so I'll create a constant holding a function in the end which I'll name updateObject, this function
again using ES6 arrow syntax expects two arguments,
the old object which I want to copy and update and the updatedValues. In this function,
I then simply want to do what I previously did in my reducer,
I want to return the updated object.
So I'll copy one and return it in my utility function. Here
I first of all have to distribute the properties of my old object, so I'll create a new object with all
the old object properties and values inside of it
and then, there are some parts which we'll probably update.
Now here I knew that it would be the counter for the given reducer I pulled this from,
here it's updatedValues and updatedValues in the end could just be a javascript object with all the
values I want to overwrite,
so I'll also distribute that, updatedValues,
so I expect updatedValues to be a javascript object here.
This is my utility function to update an object,
now let me show you how you could use it. In the counter.js file,
I'll import it,
I'll import something from and now I'll move up to the utility.js file and the something I import
of course is my update and I should export it
therefore so let me add an export statement. So the something I want to import is my update object function,
I can then use that to basically replace it whenever I want to update something.
So in my reducer, I then just return a call to update object where I pass the state as the old object
and then object with all the new properties,
in my case an object with the counter property where the new value is state counter minus action val,
and now it's a bit leaner, well due to this utility function. We can then do this for all our cases, so
update object here also takes the state and then a javascript object where we update the counter and
I need to pass a javascript object because it distribute the values of this object across the copied
old object in my utility function.
So let me quickly do this for all the other usages here too
for all the other cases, always update the state and pass a javascript object with the updated properties.
So finally last time I need to do this is here in my increment method, there I use the longer approach
of updating my state previously,
now I'll use this very short and condensed approach of just returning, whoops returning update object, there
I want to increment the counter, so plus one.
Let's quickly save all files including the new utility.js file and let's see if that works. Click
add 10 decrement,
this all seems to work so our app works
as before, you can also still store this as you see
but now we're using the utility function.
So with that, we're using update object to conveniently,
well update all our objects.
Let's also do the update
object usage we implemented in the result.js file, so in the other reducer.
So I'll import update object from and now I'll also move up to the utility.js file and then let's use update
objects here too
to return an update object where we passed the state as the to-be-updated object and then just a javascript
object with the properties that should be updated
and this allows us to then get rid of the old code we had in there and use that shorter one and the
same of course also for deleteResult.
Now there I'm also updating an array,
I won't write a utility function for that since updating an array depends highly on what we do with
an array,
adding a new element works with concat, removing with filter for example,
so therefore it's not as easy as with an object and the utility function doesn't make that much sense
for that reason.
But we still update an object here in the end
we always do when returning a new state.
So there we get the old state and then we want to overwrite the results with our updated array,
so let's pass this in the javascript object of the second argument. With that,
let's save all of that and
let's also see that in action now.
So this all seems to work,
let's store the result
also works, deleting also works.
So that's looking good,
this is update object. This is a nice utility function we can add to make our reducers a little bit leaner.