Redux for State Management 2 exercises

Replacing Cart Context with Redux

Start by copying 03-cart-context-with-initial-state into 05-cart-with-redux:

cp -r 03-cart-context-with-initial-state 05-cart-with-redux

After setting up the new project, let's return to our code editor.

Removing Cart Context & Setting Up Redux

The first thing we'll do is remo

Loading solution


00:00 First thing we're going to do is recursively copy 03-cart-context-with-initial-state into 05-cart-with-redux. Now we'll get that all set up and running. And that looks pretty good. Okay, so let's go back into our code.

00:16 Now the first thing I'm going to do is remove the cart-context component because we want to make sure that we have replaced that completely and so nothing will compile without that. Now the next thing we're going to do is create a store, a Redux store. Next thing we're going to do is we're going to add the libraries for Redux.

00:34 That would be Redux, which is a core of the state management system, React Redux, which provides the bindings between React and Redux, the selectors to go and get the data, for example, as well as the store provider, and then the ReduxJS toolkit, which is the library that makes it really easy to build and maintain Redux stores.

00:55 Now that we have all that installed, let's go create a store directory, as well as a store in our app directory. So what are we going to have in our store? We're going to have two things. We're going to have the cart, and we're also going to have the review. So let's start off with the cart. So we need to bring in the type of cart, and then we're going to define some initial state.

01:14 So this would be the structure of the slice for the cart. We're going to actually have two different slices in our single Redux store, one for the cart and one for the reviews. It's just a nice way to kind of keep the two from intermingling.

01:29 So we're going to define our cart slice as having just a cart in it, and we'll define an initial state that has an empty cart. So now we need to create our cart slice, so we're going to bring in create slice from the Redux toolkit, and we're going to use create slice to create a slice named cart with that initial state.

01:48 Now it's giving us the red squigglies because we haven't put any reducers into our slice. Reducers allow us to specify the actions for that given slice, so we'll bring in some reducers. So we'll bring in the set cart action. That action is just going to take a cart and set the cart in the store to that cart. Pretty easy.

02:07 We need to bring in payload action so we can properly define that reducer. So now that we have our slice all set up, now we just need to be able to create a store. So we need to bring in configure store also from the Redux toolkit. So if you read the ReduxJS toolkit documentation, it would tell you to build your store this way.

02:24 You define a global variable called store, and you use configure store to create that variable. Now we're actually doing the right thing when it comes to calling configure store. We're giving it the right reducer, the cart slice, all that. That's fine. The issue is that we're creating a global variable. We don't want to do that.

02:42 So we want to instead create a create store function that in turn calls configure store. All right, now we have our create store function, which is awesome. Now we just need to go and expose a bit more so that we can access that function.

02:58 Another thing we want to export is the set cart action so we can use that externally to set the cart. We also want to export some types. The most important type here is root state. That is the structure of our store. So we do command K and command I.

03:14 On that, we can see that the current store has just cart on it, and within that cart is the cart state. And then finally, the best place to put a selector is kind of in this store file here. So we're going to create a selector for use cart. That's just going to give us access to the cart.

03:31 Of course, in order to make that work, we need to bring in use selector. And there we go. Now we've got a good use cart. So in terms of the Redux store itself, we're good to go.

03:44 Now we get to the really fun part, which is how do we create and distribute this Redux store when we can't just declare it globally like we could before? Well, we can use context for that.

03:56 So just like we passed down context in our React state implementation, how about we use that context mechanism to instead define a store and then use

04:07 that built-in store provider provided by React Redux to actually pass it down throughout the entire system? Well, let's give it a go. So create a new file called store provider, and we'll start off with a store provider client component.

04:24 Now, this needs to be a client component because we're going to use that provider to provide the store down, and that provider uses context. So this needs to be a client component. So the next thing we need to do is create and hold the store. Now, there's two different ways we can do that. You can use use state or you can use use ref. I'm just going to choose to use use ref.

04:44 And then down here, I'll create a store ref that's going to hold the store. Of course, we need to bring in create store in order to create the store. So far, so good. So let's create the store. I always say if we don't have a store, well, let's create a store and then set that to current.

04:58 Now, you probably don't need to make that check because where we're going to put it in the layout is probably never going to get re-rendered. But it's okay to make that check anyway. Now, let's send the store to the provider so they can provide it down to any components. But one last thing we need to do is initialize the store.

05:17 So let's go and dispatch. All right, so far, so good. So let's go into our layout and bring in our store provider. And then we change out our cart provider for our store provider. So far, so good.

05:31 Okay, now we can go into our client components like header, cart pop-up, and add to cart, and then use our store provider. So where we used to use cart from the cart context, now we use cart from the store. And we're not going to go back in array, we're just going to get back the cart. That was pretty easy.

05:49 Okay, let's fix cart pop-up. So again, we're not going to get used cart from cart context, we're going to get it from the store. We'll just get the cart. But how do we dispatch that set cart action? So when you clear the store, we're going to be resetting the cart. So how do we go and update the cart?

06:07 Well, we bring in use dispatch from React Redux. We then use it to get the dispatch function. We also need to get set cart.

06:19 And so we'll dispatch the set cart, which will go and format the action payload that we're going to send to our reducer with the output of clear action. Okay. And then finally, let's go over and check out add to cart. So all we need here is set cart apparently.

06:38 So we need that dispatch. And we'll get that dispatch, and then we'll dispatch the set cart. Okay, not bad. Let's check it out and see if it works. All right. Seems to be kind of okay. Let's add to cart. Now it went from zero to three. Aha.

06:57 So everything looks good. Let's bring up the cart and make sure everything looks fine. We can clear the cart, refresh, zero, that's true. So the only issue is, like we had with our initial React state version, we're not initializing the data properly.

07:12 So let's go back and take a look at our store provider to see if we can initialize that state. So maybe what we need to do, because we have the cart already, is just dispatch the set cart action to the store that we just created. Let's give that a try.

07:30 So you need to bring in set cart. Now let's rerun the server. So I'm starting with a couple of cart items. And let's try it out. If I hit refresh, then we start off at two. That's awesome. And actually, let's go take a look at our SSR result.

07:47 And we can see in the SSR result, in this haze of all these HTML tags, we have one span tag that has two in it, and that is the current value of the cart. So our Redux store is being initialized before the server-side render, and we're getting the right data in the client components, and that's all going out in the initial server-side render.

08:06 So, so far, so good. Okay, now we've created our Redux store, and we're passing it around using a store provider at the layout level. Now, when we add in our reviews slice into our store, it's going to get kind of interesting as we work through some of these issues.

08:25 So don't stop now. Jump into the next exercise, and let's implement the reviews portion of our app.