Current section: Advanced State Management 36 exercises
solution

Real World

Loading solution

Transcript

00:00 Alright, let's start with the GameAction. So our GameAction type can be one of a couple of things. We can have a type of SelectSquare, and for this we're going to need an index,

00:15 which is a number. Otherwise, it can be a type of Restart and a type of SelectStep, where the step is a number. And with that GameAction, we already have a type for our GameState, you might recall, that's coming from our utils, so we're good with that. Now

00:33 we're going to create our GameStateReducer. So function GameStateReducer, this is going to take our state, which is a GameState, and our action, which is a GameAction. And then

00:45 from this, let's switch on the Action.type. And we can say for SelectSquare, this is going to be the trickier one. We'll come down here to our SelectSquare, and we're going to basically

00:59 move all of this stuff up to that. Come right up here, stick it right there. And of course, we've got to refactor a couple of things. So this SetState is no longer a thing. We do have the PreviousState. We call it State though, so here, let's just rename that. There

01:17 we go. And then from that, we get our current step, we get our history. All of this same stuff is working out pretty nice. The index is going to come from our action, and so we'll

01:30 use that right here. In fact, we can say index coming from our action, if you wanted to do it that way. And then we do need to calculate the winner. So you recall this winner came

01:50 from this variable right here. We no longer have access to that variable. We could pass it as part of our action, that would work fine. But this computation is not expensive at all. I think it's just as easy to compute that as part of this process as well. So let's

02:08 add a winner variable here, calculate the winner. Our current squares, that's going to come from here. Let's actually grab that current squares the same way that we do down here from the state history. So do that right there. And so if we have a winner, or there's

02:28 already an entry right there, then let's return. But we don't want to return undefined because this is a reducer, we're returning the new state. And so we can return state like this. And so that basically just says, hey, I'm giving you back the same state that you gave me, there's no change to this state. And React will actually say, oh, cool, I'm

02:48 not even going to bother re-rendering because nothing should change, the state didn't change. So that should work just fine. Okay, great. We also need the next value. So let's calculate the next value right here. Next value, there we go. And then the rest of this should all

03:06 just work without any trouble. So that's the hard one. The rest of these are actually pretty straightforward. So now we're going to say for our case restart, we're going to return the default state. And then for selecting the step, we're going to grab the step from the action and merge the state and just update the current step. Easy peasy. And that logic

03:24 is down here, we could have just moved it over and everything. But yeah, we don't, that's effectively what we're doing is just right here. Okay, so our reducer is ready. But we need to have our initializer as well, because we've got this whole big function right here

03:40 for initializing our state. So I'm going to make a function called get initial game state, we're going to stick all the contents of that function right here. And that actually, that should be enough. There's not really too much that we need access to, like we don't need

03:59 an argument or anything like that. We know how to get our default game state. So we're good with just getting the initial game state like this. Okay, great. So now we need to update to use reducer, use reducer, we're going to pass our game reducer, we don't want

04:16 to call the function because again, every time the app is re rendered, we would be calling it again and again and again. So we're not going to call the function, we're going to just pass as null, or as our first argument to the initial game state, we'll pass null,

04:31 because it's not using that argument anyway. And then this is going to give us our state and our dispatch. And we'll get rid of all of that. Okay, great. This is complaining

04:44 because we are not returning in the default case, I expect, there we go. We don't need to bother with the default case, because we have all of our types specified here, nobody can dispatch an action for which we don't have a case handler. So we don't need to worry

05:01 about the default case. Great. So now we just need to update all the places that we were doing our logic before to use dispatch instead. So dispatch, so it's square, here's my index. In fact, maybe we don't even need the select square, we can just inline this function.

05:19 But yeah, we'll leave it as it is. Okay, and then we're going to dispatch the restart event right here. And then for this one, we'll dispatch select step with the step as a number. Yeah, come on AI assistant, you're smarter than that. There we go. Okay, great. And let's

05:37 just make sure that the game still works. That's cool. We can go all over the place, we can have the next player and we can have a winner, we can restart and start over again like this and we get a winner. Nope, never mind. I wanted to go there. So the reducer,

05:55 this is hopefully like the place where you can see like, oh, okay, now I get why reducers can be helpful. Before we had some logic right here, we had some logic right here. Well, a whole lot of logic there, but we definitely had a lot of logic here. And we had a little logic going on right here as well. Now that logic has all been moved into one place. So

06:15 we can see what are all the things that can happen in the course of a user interacting with this thing. And they're all right here. Any state change is going to be piped through here and that is quite nice, actually. Okay, and yeah, you can't click on things that you're

06:34 not allowed to click on. And we got a winner. So yeah, O wins. All right, that's fun. Feel free to take a little bit of a break now and play your tic-tac-toe game with yourself or

06:48 a friend, go find a friend. Hopefully this was helpful in solidifying the state or the use reducer hook and that you find a lot of use out of it in the future.