- The next hook I wanna talk about is the use reducer hook.
This isn't really anything specifically about React
but it's a nice little TypeScript trick
that I can teach you that's going to help you out
with reducers a lot.
So you can see here I have my code,
everything's working just fine, but I don't have any
of the TypeScript set up for this actual code.
As you can see here, I can take in a state
and I can take in an action
and my state is obviously just whatever the state
of my actual hook down here is going to be.
So here you can see right now my state is any,
that's just because I haven't actually typed my state yet.
So let's just come in here.
We'll create a type that's for our state
and we'll just say our count is going to be a number.
And then what we can do is we can specify
that type right here.
And you'll notice we're now getting an error
on our use reducer.
The reason for that is
because our reducer here doesn't always return our state.
If we hover over it, you can see it returns
either a count with a type of anything or undefined.
And that's 'cause we don't have a default case
where we return our state.
So we wanna probably add in a default case inside of here.
And this default could just return our state as is,
or more than likely we want
to maybe throw some type of error.
So we could just say like throw a new error,
essentially saying that we have a type
but we're not actually using it properly.
Doesn't really matter what you do here,
you shouldn't ever hit this default case
if you're properly using TypeScript.
So the next thing we need to do is specify our action,
'cause we hover over our state, it gets our count
but it has a type of any
'cause it doesn't know what this actions type is.
So let's come in here,
we're gonna give a type for our action.
And we know that our action has multiple things.
First of all, we have a type which is a string
and then we also have this increase by
which is going to be a number.
And we also have this decrease by which is also a number.
There we go.
So we can type our action just like that
but now we're getting an error down here
because it's saying I need to pass both increase by
and decrease by so obviously I need
to make sure these are optional
so I don't pass down both of these, there we go.
But now we're again getting more errors
because it's saying, "Hey, I don't know
if I have an increase by when my type is increment."
So instead of doing this where you try to put all
of your different types together like this,
what you wanna do is you wanna break out your type
into individual different actions based on each type.
So we have one type where our type is specifically the value
of increment and in that case,
we need to pass along our increase by.
Then we're going to combine this here using this
or operator right here.
And we're saying we now have another type
and this type is going to be for decrement.
There we go.
And we're gonna pass along the decrease by value
which is a number just like that.
So now I'm saying it's either going to be this first type
of increment or this second type of decrement.
Now you'll notice we have no errors at all.
And the really nice thing is I get perfect auto complete.
So if I come down here, if I have a type of decrement,
you'll notice it only says that the decrease
by value is the only thing I can pass.
So if I put in a decrease by of two into here,
every time I hit minus, you now see it goes down
by two instead of one.
And you also notice when I check for my case
of my type being increment, you notice my auto complete
for my action gives me both the increased by in the type
because it knows that if my type is increment,
the only property available is the increase by property.
So be using this union operator,
by combining together all these different types,
we're essentially saying, "Hey, I'm either going
to be a type increment or a type decrement.
And if I'm type increment, I have these specific properties
and if I'm decrement, I have these specific properties.
And you can do this for every single case that you have
for a different type that you can pass in,
do a different action,
and that action can have all the properties
it needs defined on it.
And by doing this, you're gonna get really good type safety
that makes sure you never pass along the wrong properties
and it makes sure you're always passing
along all the properties that you need for a specific type.
Again, this isn't really something that's specific to React
but it's a really great way to do this.
And if you have everything set up like this,
the nice thing is your use reducer
will automatically infer your type.
So you can see here our state is account
with a number and our dispatch is
essentially a thing that takes in our action.