Zustand for State Management 1 exercises

Implement Zustand for State Management

Install Zustand by running the following command:

npm install zustand

Because we can't create a global variable when using App Router, we need to use React Context to teleport the hook wherever it is needed.

Let's start by creating the cart provider.

Creating the Cart Provid

Loading solution


00:00 Clearly, the first thing we need to do is add zustand to our project. Now, normally with zustand, you create a global hook. It's pretty easy. You call the create function that you get from zustand, you give it the schema that you want for your store, and it gives you back a global hook that you can use

00:18 anywhere and it's just by its nature global. But we know we can't have global variables. So what we're going to do to manage that in the App Writer context is we are going to use React context to teleport the hook wherever we want it. So let's go and create a cart provider that

00:36 provides a zustand hook to anyone that needs the cart. So within app, I'm going to create a new file called store cart provider. Now, that's going to get pretty easily confused with the cart provider we already have in cart context. So let's just get rid of that. So it's going to be a client component. We're going to use context.

00:56 So we're going to create context as well as use context. We're going to use state to store the hook that we will then use in that context. Next, we're going to create from zustand. That's going to allow us to create that hook that we're going to pass around through that context and then we'll bring in the type for the cart. So the next thing we're going to do is create

01:14 the store hook creator function. Now, just like we did the Redux, you can't have a global variable. So we're going to create a function that allows us to create a hook on the fly in the layout every time we render a new layout. That is this create store function. It calls create with the schema. So that's going to have the cart as well as set cart.

01:34 Then we give it the cart value initially and we have a set cart that simply just sets the value with the cart. You can see why people like zustand. It is very, very simple when it comes to the actual implementation of zustand. It's a little more complex because we're doing this hook within a context thing

01:53 because we're in the context of the app writer and we can't have any globals. Otherwise, it's really nice in terms of an API service. Next, we'll create our cart context. That's just going to have the output of the create store or null as it's initialized. Then we'll create our custom hook.

02:09 This custom hook is going to get you the zustand hook. So use cart will give you the zustand hook and then from there, you can get the cart or get set cart or both if you want. Then finally, we create our cart provider that is going to provide our store down the line and we're going to use

02:26 use state to hold the create store that we just created. So let's go over in our layout and bring that in. So now we'll get cart provider from our cart provider. Otherwise, it's exactly the same thing. It takes a cart just like we did before. So let's go and make our changes to our components. We'll go into components, we'll start with a header again.

02:44 We'll get the use cart from the cart provider. Then just to show you how this is going to go the first time. So what we're going to get is a cart hook from use cart. Then with that cart hook,

03:01 we're going to get the state and we're going to return just the cart. That's one of the nice things that zustand allows you to do. The hook that you get back from zustand, you basically just give it a selector and that's how you get just the values that you want off of the state.

03:20 Now, we can make this a lot simpler by just simply doing use cart here. It looks a little odd. You're basically just calling a function that you would then in turn call, but it works. Let's go to our cart pop-up. Again, we'll get the use cart from the right spot.

03:39 This time, we'll get the whole store including the cart and the set cart. Then finally, over an add to cart, we'll go get use cart from our right spot. Then we'll just get the set cart and let's see, let's try it out. All right, looks pretty good. Seems to have the initial cart. Let's add the Castle t-shirt to the cart.

03:58 Pretty nice. All right, cool. So that's the cart implementation in zustand. It was easy enough. Let's go just do reviews right now. So to do reviews, we're going to go back into our store and create a reviews provider. We'll bring in everything we need and then we'll create a create store function that's going to give us back

04:16 a zustand hook that has the array of reviews, as well as set reviews to go and set those reviews. Next, we'll create our reviews context. We'll create our use reviews custom hook. Again, that's going to give us that zustand hook. It's not actually going to give us the reviews, it's just going to give us that hook that we then

04:33 call to get either the reviews or set reviews or both. Then finally, we create our provider. Again, we're going to use usestate to hold the state of the store. Now, let's go and implement this by going and bring it into our products. We'll bring in our reviews provider,

04:53 put it at the top of our tree, and there we go, looking pretty good. Now, let's go and actually implement it over in average writing. So bring in our use reviews. Now, we don't actually need to bring this in as a prop anymore. That's nice. Then we'll call that use reviews hook. That'll give us back the zustand hook.

05:14 With the zustand hook, we will then give it a function that will take the state and return the reviews. Of course, this guy is now complaining at us that we're giving it reviews and we don't need to. Let's get rid of those and save. But now we need to port reviews. Let's go take a look. We don't need the reviews,

05:32 but we do need user reviews, and we'll get reviews and set reviews from that. Now, we're not using set reviews yet, except we do by just adding it on here. Let's give it a try. Refresh looks pretty good. Let's add another cool Castle shirt.

05:55 Again, with the one, submit review. Looks great. Let's go make sure that it is in the SSR at output. There we go. Another cool Castle shirt in our server-side rendered output. That means that we are initializing

06:12 our zustand store properly and at the right time so that it's ready for server-side rendering. As you can see, why zustand is so popular because it is just this simple. Next up, we will re-implement this in another model entirely, and that's the atomic model using

06:31 another Daichi Kato library. This one is called Jotai. Thank you so much, Daichi, for actually giving me a state manager that is a lot easier to pronounce.