Redux Toolkit Tutorial – JavaScript State Management Library

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Redux toolkit is the recommended way to use Redux. And it's generally what you should learn if you're getting started with Redux. John Smith yoga is one of the most popular instructors on our channel. And he teaches this course. What's up everybody? This is John from coding addict, and welcome to a Redux toolkit tutorial video. As far as the elevator pitch for Redux toolkit, essentially, Redux toolkit is good old Redux, just with batteries included, meaning unlike traditional Redux, all useful packages are by default part of Redux toolkit. So instead of wasting our time, on annoying boilerplate setup, we can right away get the work. During the tutorial, we're going to build this current application. And in the process, we'll see all the cool features of Redux token inaction. So things like store slash reducers action creators, and of course, create async thunk. As far as the requirements, if you have not worked with Redux before, my expectation is that you are at least familiar with use reducer hook, since they share a bunch of common terms and syntax. And just in case, you need a refresher on use reducer. In the description of this video, I will leave a link to my react tutorial video where I cover use reducer in great detail. If you prefer learning by building much of whole project and enjoy my teaching style, you can find all my courses johnsville.com. Again, the site you're looking for, is the dub, John smelled about calm. In order to follow along, you will need a star and you can find it in this GitHub repo. So look for my profile, Jon's Malga. The actual repo name is Redux toolkit tutorial, then the name of the repo that you're looking for an IRS Redux toolkit tutorial. Once you get here, just pick the option that makes the most sense to you. I think in my case, I'm gonna go for download zip option, then I want to crack it open. In the folder, you'll find two more folders, the final as well as the starter. And needless to say that in the final one, you'll find the complete source code and then in a starter is where we'll do all of our work. So make that sucker out. Let me open up the text or Visual Studio code. All right away sit side by side. Now, this is a standard react application, I used create react app. The only difference is that I removed some boilerplate code. And I also added some resources shown here, what we want to do is run npm install, and also npm start. So npm install and npm start, and there is an app. So at the moment, notice there's only two, we have some core items, which we'll use in the beginning as our data, and also a few icons. I'll discuss them a little bit later. Index CSS, all our CSS and also of course, index js. So once you get the repo, once you get the star, install all dependencies run npm start, you should see in the browser, a boon to with, I believe it was Redux token. And if you do, we're in good shape. And we can proceed to the next step. In the starter, you'll also find a readme file, where I laid out all the steps we're going to take as well as some useful links. And first, if you want to find more info about Redux toolkit, you can always utilize this link. So this one goes directly to their docks. And we have a few ways that we can add Redux toolkit to our project. First, we can go with shred up template. So in that case, instead of going and BX, create react app, and then the app name, we also add this hyphen, hyphen, and then template and Redux. Now, from my experience, they add way too much boilerplate. So essentially, I always avoid that. In general, I just go with the Redux toolkit. So I set up the application, let's say would create react app, and then install the toolkit separately. And we do that with npm install and then add Redux J, s, and then forward slash token and also add react. Redux. And I'll talk about in a second. Now, let me just quickly mention that if for some reason, you get some issues when you just run MPX, create react app. And again, it's not specific to this template one. If something goes bananas with MPX, you can always try to go with create react app, and then the latest one. So this is just a side note. Now back to the toolkit. So when we install Redux JS toolkit, we actually install few libraries. So we installed the Redux, which is going to be our core library. We also installed imer, which is going to allow us to mutate the state, we install Redux thunk, which will handle the async actions. And also we install reselect, which will simplify the reducer setup. So these things, of course, will only make sense if you already have worked with the Redux. So this is already provided for us. And of course, you will see all of those things in action. And if you didn't work with Redux, before, the worry, of course, I'll explain all of them. And also, as an extra, we get through right away, Redux dev tools, and also combined reducers, right from the get go. Again, if you haven't worked with Redux, I totally understand if none of those things make sense. But don't worry. We'll talk about them later. Now, why we own So install this package, the React Redux, or say, Redux can be used with any front end framework. It's not specific to react in order to connect our application to the Redux, this is where we'll use the package by the name of React Redux. Now, needless to say, that of course, if you'll take a look at the package json, you will see the both packages, you'll see the toolkit as well as the React Redux. But just so you don't think that there is some funny business going on. Let me copy this line of code. Let me install both packages. And once the install is complete, we can start setting up our Redux store. So the install is done, we go with npm start. And if we take a look at the package json, you will find the docket as well as react Redux. And with this in place, now, we can start setting up our application with Redux toolkit. Okay. And once we have installed all the dependencies up next, I want to set up the store. And you can think of store as the Empire State for your application. So remember, previously, we use context API. Now in this case, we'll use toolkit and we'll set up the store. The syntax is following. First, we want to create store Jas, somewhere in the source, we want to import, configure store function from the socket. And yes, in order to speed this up, I'll just reference it as token. Please keep in mind that of course, I'm talking about the Redux token. And then in this function, we want to pass in the object in the object, there's going to be a reducer property, which is going to be object itself. And then in here, we'll set up our features. And I fully understand that, I mean, this can look somewhat fuzzy, don't worry, as we start setting up the features, you'll see everything in action. So for the time being just bear with me. And then once we have a store, we want to export that. And this is the case where you can export this as default. So the difference, of course, is just export default, and then store, or you can go with named export. And then we want to go back to index js, we want to import store from the store file, as well as the provider. From react Redux. Like I said, this is the library that connects Redux store, or Redux to our application. And similarly to context API. We want to wrap our entire application. So we want to grab this provider. There's a store prop, and we just want to pass in the store coming from the store. Wow. So let's get cracking. First. We're going to go with store Jas. In here, once import, configure store. So import, we're looking for configure store, notice right away, I have a suggestion for that. And then let's set up that store. Like I said, the moment might look somewhat funky the moment we'll set up some features, it will make sense. So let's go here with const And of course, I'm adding export as well. When store matters equal to configure store, let's passing the object, let's set up a reducer is an object itself. And for time being, it's going to be empty, and most likely, we'll get the warning in the console. Don't worry about it. Again, all of this functionality is coming up and learn. Let's navigate to index js. Let's import both of the things. Let's go with import, and store. This coming from the store file, of course. And also we want to get that provider. So we import and then provider. Now that is coming from react Redux. And now let's wrap our entire application. So let's say provider here. Let's close it out. Let's wrap our app. Online, we want to set up a store prop, and we want to set it equal to our store. If have been bricked, we are heading in the wrong direction. So then we can set up the slides. Again, like I said, if you see this warning, don't worry, we'll fix it in second. Beautiful. And once we have the story in place. Now let's set up the slice. I fully understand that this name is totally funky, you're like what slice are you talking about. And I want you to think of slice as the feature of your application. So if we take a look at the complete project, you'll notice that, yes, we have the core functionality. But we also have the modal. And you can think of it as two features our application. So we have one feature for the modal. And the second one is going to be for our cart. And of course, the bigger our application. The more features we're going to have, in the Redux toolkit land, it is called slice. Now, in order to set up slice, a common convention is to set up a features folder. But of course, naming is always up to you, then whatever is going to be the name of the feature. So in my case, it's going to be card. That's why I'll set up a card folder. And then we want to set up a file. Again, like I keep mentioning the naming is up to you. But again, typically, you'll go with whatever feature and then slice Jas, now in there, you will want to get create, slice, and don't worry about this one, but create a sync thunk a sign of our move it worry about that later. And then we want to invoke that function, create slash, we want to give it a name. Again, it's totally up to you. But in my case, I'm gonna go with cart. And then we have initial state property where we just set up whatever state we want. In my case, I'll set it up as a separate object. And in here, I'm gonna go cart items with an amount. So how many items I have in a cart, what is the cart total, both of them are zero. And that is loading true, because eventually we will load this from the API, then a log the sucker the carts light. In there, we'll have the reducer. And of course, I'll talk about this one a little bit later, once we get there. Eventually, where we want to do is in the store, we want to import cart reducer. So that's going to be the function that controls of this state in our slides. So think about application, we'll just split up the functionality where this slice is just responsible for the cart. And this reducer specifically, is going to modify it, whatever functionality we set up. And then in that reducer that we set up in the last video, notice, there's a complaint that there's no valid reducer. Now we want to set up a key. Now key name is really up to you, just like everything else. And I know that you're probably sick of hearing this, but I just want to make this clear, where this is totally up to you. You can call this banana pudding, if you want. Just remember that later. Once we start setting up our functionality, yes, of course, you will have to access this name. So therefore I'm gonna go to court. And I want to set it equal to reducer. So the function that will have access to and a function that will allow us to control this piece of state for this specific functionality. Hopefully, this is clear. So now, let's go to source, we want to create a new folder, like I said, common convention, we'll call this features so features our application, in our case cart and modal when let's create another folder. And we're gonna go here with cart. Then inside of the cart. Let's go with new file. And we're gonna go with cart slice, Jas. So once we're here, we want to import we want to import and we'll say create, slice. Now for some reason, it does not, it does. So ABS suggestion, let's right away, invoke it, I'm going to call this const. CART slash node is equal to create slash, it's a function, we pass in the object. And here we can set up a bunch of properties. So first, we want to set up the name. So I'm gonna go here with cart, then we want to go with that initial state. And this is the case, since I have more properties, might as well set it up as a separate object. So let's set up here initial state. And then we'll add cart items, which initially is going to be empty array. But when we'll take a look at multiple approaches, the local data, and then the data coming from the API. I also want to go with amount. So how many items I have in the cart, and please be aware that I'm not just talking about the products I have, in my cart, I'm actually looking for the item count. So how many items of that specific product app, this is going to be that amount, hopefully, that is clear, when we want to go with total. So total money, both of them zero, initially, and that is loading, because eventually, we'll pull this from the API. So that's going to be our initial state, once we save notice right away, initial state, in here, references the initial property. And then we want to log the sucker. And we want to quickly import in the storage errors. Now, in a second rule, do more proper setup, I just want to showcase what do we have in the cart slides. So let me save it, then I'll navigate back to the store. And for time being, let's just import the entire file. Like I said, more proper setup is coming, we'll just go here with the features like cart, and then cart slide. And once we import, of course, we right away, invoke the file. And here we'll see that console log. So we'll have some actions here. Something that we'll discuss a little bit later, once we set up some reducers, we have case reducers. Again, something we don't need to worry about right now get initial state, again, a function that gets the state name. And then notice all the way in the bottom we have that reducer. So this reducer is the one that is going to control that state in the slight. And that's where we want to export that we want to export this. And in the store, we want to come up with a key and set it equal to that reducer. So let's try this out and we're gonna go with cart, then instead of just getting the file. I'll actually look for that reducer. But I'll set it up as a default one. So for time being, I'll comment this one out, we'll come back to this one. Because again, we'll talk about these actions eventually. And now I just want to export that reducer. Now there's a million ways how we can export us. In this case, I'm gonna go export default. And then cart slice dot reducer. Again, this is an object, and this is a property. So let's export this, when in the store, we want to import. So I'm gonna go with cart, not slight, but reducer. Again, if you want to name this differently, of course, you can imagine we're going with from now go with cart equals to cart reducer. And we shouldn't see any error messages anymore, because now we have the proper setup. So now we can take a look how we can access the data first from that initial state. And then of course, eventually, we'll also take a look at how we can set up functionality to control this, but our first step is going to be accessing this data. Okay, before we go any further, let's also quickly install Redux dev tools. And the good news is that as far as the code, we don't need to add any configuration. Basically, the moment we install Redux docket, we're good to go. However, when it comes to browser, we do need to install extra extension. And the extension you're looking for is this one, Redux dev tools. In Chrome, if you want to install extension, just go to your extensions. And then more specifically, look for open Chrome Webstore. Not in here. Look for the Redux one, not the Redux. Okay, I'll just Redux. So this is the extension you're looking for. And once you do that, let me open this up in the big browser. So that's my localhost 3000. You'll notice a tab, a Redux tab. And here we'll be able to find a bunch of useful info. Now at the moment. I mean, we have a clean application, we only have the state but yes, eventually once we set up the reducers the actions and all that, yes, this is going to be a very useful Till now, at the moment, the only thing that I want to showcase that this is our state. Notice, that's my cart, cart items Amount total is loading. And yes, of course, in our store, once we add more reducers, all of them will meet over here. And that's why this tool is very useful, because as We'll dispatch our actions, will clearly see how our state changes, beautiful animals, we have set up the Redux dev tools. Up next, let's see how we can access that initial state in any of the components. So we have the initial state in the slide, let's say that I want to set up a navbar component where I want to access the amount the setup is following, where we do want to create the components folder, then nockberge S, and then there will import Cart icon. So that's the component that's coming from the icons folder. And I'll discuss how we can set up the component E in the following video. Because at the moment, I do want to focus on the state value axis. And then we want to import use selector. So that's a hook coming from react Redux. And then in the navbar component before the return, we want to invoke use selector. The selector is looking for one thing, looking for the function as a parameter, we get access to the entire state. So we're talking about the entire store. And then, in our case, we just have the cart. But eventually, we'll add more reducers over here. So since this is a parameter, of course, we can call it whatever we want. So you'll see probably state, but actually, my preference is to call this a store, because that signals to me that that entire store, so the entire state of my application. And then more specifically, I'm looking for dot cart wire, because that's the name of the property over here. And then initial state, if you remember, we do have the amount property. And of course, there's million ways how we can set this up. For example, we can just return from this function this amount, or, since in this case, we're returning the entire object, we can destructuring. So let's try to set this up, where in the source, I want to create a new folder, I'm going to call this components over here, run, and let's set up that nav bar. Now bar j s, in here. Like I said, first let's import Cart icon, something we're going to discuss in the following video, then we also want to get that use selector. So it's a huge selector hook that is coming from react Redux. And now let's set up that navbar component. So I'm going to use my extension, I'll set up the number. And first, let's set up the return. And then we'll worry about the actual state. So let's say here. Now, I do want to add here a dev. So instead of the dev go, or I'm sorry, instead of the novel's go with Dev, let's add a class name of nav center. And here, we want to go with heading three or Redux toolkit. And after that, let's save it. We don't see anything. So let me refresh. don't see anything in a browser. And of course, the reason for that is because I didn't import in the objects. So let me go back. And in the app js, let's import that navbar. And then let's set it up over here. So what I want to do, as far as the return in app js, I just want to go with Maine, and then the number. So instead of the getting to Redux toolkit, we'll go with main tags. And then first, we'll set up the navbar. And then we'll set up the rest of the card items as well. So that should be our navbar. Okay, that's awesome. As far as the other stuff, I think I'm gonna go here. We have a card icon, but that is going to be placed in the nav container. So right after this heading three, we're going to go with div with a class of nav container. And in here, let's set up that cart icon. Yep, that is how it's going to look like online. Let's go with div with a class of amount, container and then paragraph with a class of total, total hyphen, amount. At the moment, let just place a zero here. Let's save this and now let's see how we can axis, the entire state of our application. So first, let's just log the sucker on, say use selector. So that's the hook. And like I said, it's looking for one parameter, which is going to be our function. And then inside of this function as a parameter, we get that entire store. So for time being, I'm going to call this store on all log it. Let's say that the only thing that I want to do in this function is log the store. And what you'll notice in the console is our entire state, which is just awesome. If you asked me. So take a look over here. Yeah, cart items, we have a mount, and we have the total. So again, I know I'm repeating myself. But essentially, the idea is that using this huge selector, notice how we don't need to pass anything coming from the specific slicer, nothing like that we can right away in this function, axis, our entire store. And essentially what we want to do, we want to return something, whether that is specific property, for example, amount, or, of course, you can return the entire cart, and then you can destructure. So first, let's just set it up where we return the amount. So notice over here, we have undefined in line five, because we're not returning anything from this function. Yep. Let's set up over here in the paragraph. And then we'll take a look at the structuring option as well. I don't think I'm going to leave this for your reference, because again, we'll set up multiple ways anyway. So first, let's go with amount. And now one is equal to, let's again, invoke use selector. Let's pass in the function, we're going to be setting up the arrow function. And I'll go right away with implicit return. So again, in here, we're accessing the entire state of our application, and we go store, cart, because that's the property value. And yes, once we add more reducers, in our store, then of course, we'll be able to access. So I'm going to go here, let's say with modal, I'm not going to pass anything in because I do need to set up the reducer. And of course, we'll be able to access with store dot model. Hopefully, that is clear. And this is very, very useful. Because again, we don't need to import anything specific from that slice, we have access to entire store. And then let's go with a mount. So this is what I'm returning from the function. Probably it's not going to be surprising. If I pass here, the value, still going to be zero. Now let's test this out, though. Let's go to our features like, and let's change this around, let's say there's going to be five items. Number one, I said, notice, now of course, I have this value of five. So we know that our functionality works. And like I said, there's a million different ways how we can set this up. And one of them is actually destructuring. So I know that I've been returned store dot cart, which is essentially a object. All right. And then inside of it, I have the amount property. So this is also valid and valid and not changing, we didn't get any bugs. So that's how we can access data from our slice, we need to pick the component, we need to use the user selector in here, we pass in the function as a parameter or this function gets the entire store. And then we just need to pick what we want to return. In my case, I want to return Clark from this function. It is an object and it represents a vis initial state. And more specifically, I'm looking for him out. That's why I the structured, and then I have displayed here in the return. As far as the icons in this project, I decided to go a different route, where I use the arrow icons site. So once you navigate there, you will notice a bunch of nice icons. And essentially, I just set them up as components. So let me show you with one and then you will understand the general concept. Just pick the icon you want. In this case, I think I'm gonna go with this bad one. As far as I noticed, there's really no difference whether you go with JSX or SVG. So let me just copy this one. Let's navigate back. And then in the icons. You'll notice full blown components that I will right away export. So let me keep scrolling and I'm going to call this testing. So I'm going to say Export const. That's going to be my testing component. In here, you just want to set up the value on a return. So this essentially will be the icon. Now, I am styling it though, in the CSS and in a second, you'll see what I mean. So I have this testing icon right now. That's the return that I just copied. So now let's navigate to the navbar. Since I already have the input for the cart icon, and let's set up over here, the testing one as well. And we can place it anywhere we want. So let me put it side by side. And you'll notice that this is a giant or I'm sorry, well, I already applied the styling. So maybe this is not gonna work over here. Maybe let me set up here, the fragment, and then you'll see what I mean. So let me move the sucker down. Again, this is just temporary, you don't have to follow along. But you will notice that if we don't apply the styling will get this massive icon, basically, that's the default that they provide. So in the styles in the index CSS, I added some styling for specific icon. So now I'm talking about the cart icon. And also, same applies for these ones over here, as well. So not only you will need to get the icon. But notice over here, I applied some length, as well as the color and of course, you can add more style. So essentially, that's how I set up my icons where I created icons, Jas. And here you'll find three icons, so one for the cart, and then the other ones for the actual cart items. And I imported the icon from the hero icon. So I set it up as a component I export, and then I import in any of the components that I want. And then I just need to apply a little bit of styling, you want to target the SVG. So now let me remove testing one. And also let me remove it from the icons since we won't use it. And now let's proceed to the next step. All right, and up. Next, let's work on our core items. So at the moment, it is empty array. Or I did prepare an array of products, just so we can set up the initial functionality. Yes, eventually, we'll fetch this data from my API. And in the process, we'll practice of how we can set up asynchronous operations in Redux toolkit, but for the time being, this will be hard coded data. And it is located in the car items. And as you can see, it is an array where each item is an object with some properties. So what we're going to do, we're going to set up the initial state equal to that array. So of course, we just need to import and then repeat the same steps, like we did with an amount in our bar. However, since we have an array, we'll have to iterate over, and all of that cool stuff. So first, what I want to do is go to the cart slash, and we want to import, we want to import those cart items. So let's go here with cart items, it is a default export. So it doesn't really matter how we call it here. And then we need to go to levels up, we're looking for the cart items. And in here, where we have the initial state, let's set up our items equal to current items. Now if we want to see that, we can either go to the navbar. Since in there we have the use selector. And we can, of course log it, or we can take advantage of the Redux dev tools. So let's navigate here. Let's refresh, just so we're on the safe side, if we navigate to the Redux dev tools, Now what you'll notice that cart items in the cart is an actual array. And like I said, each object represents that item with a bunch of useful property. So our next step is going to be setting this up in the App Cache, where we'll grab them, we'll iterate over and learn for each item will return a component with the image the title, rest of the stuff. Not bad, not bad. So we set up the card items equal to an actual array instead of an empty one. Now let's set up two more components, the cart container Jas and cart item Jas, and just the showcase. So this is going to be the container where we'll have all of the items as well as the total, the clear cart functionality. Now eventually we'll add the model but the idea won't change. If we click on click But then of course, we'll have empty cart. And then we also want to set up that cart item, where again, will display all of this info. And yes, we'll practice on you select her again, we're in the cart container, we not only want to get the cart items, we also want to get the total as well as the amount, because we'll use that amount to display some things conditionally. In this case, if the amount is less than one, then we'll display this. And if there are some items in the cart, then of course, there's going to be a different logic in the current item, we'll just pass in the ID as a key, as well as the properties of the item. And then we'll restructure it. Now when it comes to card item, for the most part, we'll get there our action creators, which of course, we'll set up a little bit later. So for now, we just want to worry about rendering of the cart items on the screen. So let's get cracking where I want to go to components. Let's go here with cart container Jas. And I also want to set up that cart, item js. Now when it comes to car animal work on that one, in next video, for a moment on us shouldn't be cart items should be called item one. Now let me fix this one as well, where we're gonna go with cart item. Now we want to import that in the cart container. So let's set up this component as well. So our A, F, C, E, and let's right away, import that cart item. So let's go here with cart item again, and we want to navigate to the app. Jas, we also want to get that cart container. So let's get that one. And I'll place it right after the container, meaning the navbar sorry, and we should see on the screen container. Awesome. Now what's next? Well, let's take a look at the readme where we do have the cart item, we also want to get the huge selector and not from my application state, I want to get the entire cart. And I'll just the structure columns total, as well as the amount like I said, the month where we used to display conditionally empty cart. Again, I already showcased that. But let me show you one more time. This is what we want set up if the cart is empty, and we'll control that with a mod. Now if there are some values in the cart, then this is what we want to return, we want to go to the section header, iterate over cart items. And then also in the footer, we want to display the total with the clear Cart button. So let's set this one up. Where I'm going to go with import that huge selector from react Redux. Let's right away access all of the items. So let's say here const. For cart items, total. Also we want to get the amount. And all of that is equal to us. So selector, let's pass in the function and what we want to return. We want to go here with store or state, or we want to call it store and then cart. So we get all those values. Right away, let's set up that condition where I'll say amount is less than one. If that is the case, what we want to return. Well, we want to go here with section. Then let's add a className. cart. Let's set up some logic over here. Let's say here, better. And side of the header, we'll have a heading to your bag. And then right after that, let's go with heading four. And we'll say empty cart. Now we do need to add here empty cart. Last, let's add a text your cart is currently empty, or your bag is empty. Let's save it now since the amount is zero, this is exactly what we display. So in order to see the items, of course, you will have to navigate back to the cart slash. And again, for time being we'll just hard code this, don't worry. Eventually, we'll set up some action creators that control this logic, essentially, we'll set up some reducers. And by default, Redux toolkit is going to give us those action creators. So let's go back to the cart container. And right after this one, we want to set up another return. So as you saw, this one was if we have less than one, and now since we hard coded we have four. So on here we want to go with another turn. Another section, and we're doing a class. So class will be equal to cart. And then the same deal, we want to set up that header. So header over here. And inside of it, we're just gonna go with heading to your bag. Your bag. Let's save that one. Yeah, so no, this is wrong. So it should be className. Then we want to iterate over the card items. So for the time being, we just want to set up a dev ban, we want to grab those cart items, we want to run the map. And this is the actual array correct. And then for every item, we want to return that car that we just set up, we want to pass in the beta. Now on the screen, we'll just see that text, whatever we have over there. From here we have the car app, but eventually, yes, access it correctly, the split. So we're mapping over, I'll call this item. So now I'm talking about each and every object over there. Let's go with a return. One, let's set up a cart item, we do need to pass in the key since this is react. And I already know that there's a an ID property. Now if you don't believe me, you can navigate over here. And you'll clearly see that so each and every item has that ID property. So let's say here.id. And then I want to use the spread operator dot dot dot, and then pass in rest of the properties. Let's save it. So since we have four items, we have four cart items on screen. And then right after this one, right after this div, let's set up a footer. And this is where we'll display the cart total, as well as the clear button cart, which eventually will invoke the modal, clear the cart. So I'm gonna go with a horizontal line here. Then let's add a heading to with some beta. So total span. And inside of this one, I want to set up $1 sign I'll say total. Yes, the moment it is going to be zero. Don't worry about it. And as I know, I've actually messed it up over here, it shouldn't be div with a class of CART total, my apologies. That's why the CSS is not correct. And after that, we want to go with that clear Card button. So still within the footer, we want to go with button. Let's add a class right away show btn, clear BTN. And let's say clear cart. Let's save this, let's refresh so we don't have any errors. And this is what we should see on a screen where again, we use use selector to access our entire store. More specifically, we looked for cart, which were presented that initial state in the initial state, we have all these values, so we're able to structure and then we check for them out. If it's less than one, we display the message. If we have some items in there, then we just iterate over them. And for every item will return that corner. And then below that, we have total, which at the moment is zero, eventually this will be dynamic, as well as the clear Cart button, which eventually will remove all the items from the cart. Awesome. On Up next, I want to set up the cart item where we're passing in all of the data from the cart items. So we go here with dot, dot, dot and item. Basically, we spread out all the properties so we can access them, of course here when we destructure the props. And then we just want to set up some return with a image title and rest of the stuff. Yes, of course, none of the buttons at the moment will work. But at least we'll have a better looking card. And also we want to get to icons from the icons, we want to get the rest of them the chevron down and Chevron up. So I'm going to navigate to the cart item first. Let me grab both of them. Let me get the import ban we're looking for Chevron down and Chevron Chevron up. After that we want to go in the structure of the prompts. So we're looking for ID, image, title, price, as well as the amount and as far as the return. Let's start over here with simple article. So we want to go here with article on let's add a class off cart. Item line we want to go with image and the source will be the image. So let me say here dynamically image. And as far as the alternative? Well, we have the title for that. So let's save it, and we should see the images. And if we do, and of course, we can proceed to the next step. After that we want to set up a dev heading for is where we'll display the title. So let's save that. And then we also want to set up the price. So let's say here heading four with a class of item price, which comes with a little bit of styling. And then I'll add the dollar sign and I'll say price, save that, then we want to set up the button. So right below, we'll go with button event class and remove FnB down. And we'll say remove, save that. And then we just want to set up those buttons to increase or decrease the amount. So we want to do that right after this. So this is where we set up the heading for isn't the button. But after that we want to go with another day, if there's going to be no class, we want to set up a button. Let's call this amount, iPhone BTN. And then let's add that icon over here. So in this case, I want to go with Chevron up, let's close it. Okay, good. Then we want to copy and paste and set up the show run down. So the class is going to be the same. On button here, we just want to say show run down and in between them. This is where I'll place the amount. So let's say here, paragraph, class name, amount. And we want to render the amount, say, a month over here with Sarah. And for all of them, we have one. Of course in the following videos, we'll set up the functionality that allows us to change that. And with this in place, now we can start slowly adding our first reducers. Okay, so how we can set up the functionality with Redux toolkit. So if you remember previously, we need to set up the action we need to dispatch. And then we always always needed to return a new state. And then just of course, copy the values and all that. Now, this is not the case with Redux token. In fact, it's much, much, much easier. And the way we can do that, we simply go with a reducers property in the slash, again, key value pair, my guess I'm going to call this clear cart, that's going to be the name of my reducer over here. Now as a parameter, this function gets a state. And notice how we don't have to return anything. I don't have to return the new state, always avoid the mutation. Basically, remember what user reducer we always always always needed to return a new state. We don't have to do that right now. Why? Because when we installed Redux token, we also installed ima library, which behind the scenes does all the heavy lifting. So in our case, we can modify the state or mutate the state directly. And yes, you're not hallucinating. This is clearly the code that mutates the state. The reason we can write such code is because Redux toolkit comes with email library. Now, it's also really cool that if we take a look at cart slides, something that we're logging right now, in the current slides, dress, we have actions, and the moment we create that reducer will be able to see the action created by the name of Yes, exactly the same clear card. And what that means is that we don't need this code. Again, remember what user reducer, we set up the action, we set it equal to string, we didn't set up the action creator, per se when we use use reducer. But the idea would be that we actually set up a function that returns that type. So we don't need to run around with this variable basically have right away function. And optionally, we can also pass in the payload. Now, why am I saying this? Because now we can directly use this clear cart, we don't need to set up the variable, we don't need to create the function. Essentially, it's already provided for us. And then in order to invoke it, we need to get another hook from the React Redux, and this is use dispatch. So remember, with user do, sir, we use dispatch, in this case, we right away get it. If we invoke use dispatch, and then we invoke dispatch, so whatever we're getting back from here, and we just pass in action creator. So yes, we do need to import clear cart. That's why we're exporting or here, notice export const And then name, import, or I'm sorry, name, export. And then we just need to use it. Don't worry if some of this seems confusing at this point, it will make total sense, once we complete the entire setup. So first I want to navigate to cart slice. And like I said, we want to start over here, by setting up that reducer, the one that is going to clear the cart. So let's go here with reducers, there's going to be an object inside of it, we just need to come up with name for our reducer, okay, so it's going to be clear card, it's going to be a function that gets the access to the state, now also have access to the payload, basically, would say we want to pass in the ID, something we'll do a little bit later, which is going to be a second parameter for now. We don't need to worry about it. I'll set it up as a arrow function. And like I said, I know I keep repeating this, but we can mutate the state directly. Because behind the scenes immer takes care of that. So we can go here with state, then what is the value? Here? It is cart items, what do I want to do, I want to set it equal to an empty array. That's it. That's all I want to do. And now let's go to the cart slash, Let's uncomment the log. And we'll see in the console that yes, we have name and all that. But now in the actions, we have a function, we have action creator, by the name of clear cart. And again, the beauty of this is the fact that we don't need to set up anything manually as far as the action as far as the action creator, we right away get in by default. And the only thing we want to do is bass in the clear cart function into whatever we're getting back from dispatch, or use dispatch, and then pass it in. So let's go back to the slides. And instead of logging, which, as I said, I'll comment this out, we want to go with export const. So all of these will be named and yes, we'll add more functions, of course over here. And let's go and clear cart. And now where are we looking? We're looking in the cart slash dot actions. So let's set it equal to cart, slice, dot and actions. So from that object, we export it. And now we just need to decide well, in which component, we're going to use it. Of course, in our case, that will be card container. Yes, eventually, we'll set up the model. So we will move that functionality from the card container to the model. But for now, let's just see how we can invoke it in here. So let's say use dispatch, that's the first one, when comma. And below or above, it doesn't really matter, we want to go with that huge dispatch. So const, this is going to be equal to dispatch, whatever we get back, use dispatch invoke, we don't need to pass anything. And then let's keep on scrolling, keep on scrolling. This is where we have our button. And now we do want to pass in the arrow function because of course, I don't want to invoke this immediately, I only want to invoke it when we click on a button. So let's say here, on click, run, what's passing the arrow function. And we'll say that every time we'll click on a button will dispatch an action. In here, let's pass in that clear cart. Again, the beauty here is that we don't need to do all of that manual labor, we just pass in the function that said no, that didn't import, it was gonna go back, we want to go with clear cart, which is coming from the cart slice. Now let me save it. And in here, it says unknown event handler. Because I probably did some oil. There's not right. And once we click, this is what we'll see. Now we're not displaying this one, the condition simply because we're not controlling the amount yet. Don't worry, all of that is coming up. For tambien. We are just displaying the heading two with your bag here. And it'll basically since we removed all of the items, since it's equal to an empty array, we just have the your bag and the total. And with this in place, now we can set up rest of the reducers. And while we're still on the topic of state management, in the Redux toolkit reducers. Let's also cover an alternative option. And that is simply the fact that we can return a new state from the reducer. So let me comment this one out. retype your return, but we need to be aware of the major gotcha now following whatever we will return from reducer, as our new state will become the new state. So let's say if I'm going to return a, an empty object, yes, our state will immediately turn into an empty object without any of these properties. Same works if I'm going to return here, empty array. So let's say if I return an object. And if I just say, Clark items, equals to an empty array, yes, I will update this property. But automatically, I'll remove versions, just to showcase that, let me save it. Let me click on Clear cart. And you'll notice that now, I am nothing here as far as the amount as well as the total. And I can clearly see that if I navigate to the dev tools. So let me open up the Redux dev tools on a small browser window. And then when it comes to our state, notice, all of the properties are missing. Now, only the cart items is there. So let me comment this one out. And let's take a look at the use case where this is going to come in handy. So in one of our upcoming projects, will have some pages. And in there, we'll have a bunch of inputs that are going to be our state values. And essentially, there's also going to be a clear button. And the idea is like this, once the user starts typing something, let's say changes some values around here. At some point, maybe he or she wants to clear out all the input values. So in that case, we're going to take that initial state. And we'll just return that from our reducer. So let's say you set up your state with whatever default values. And then when you have the reducer, that just sets it back to default, you just pass that initial state as a return in your addition. So that's one of the use cases where this comes in handy. But we do need to be careful, again, whatever we're going to return from the reducer will become that new state value. So if we omit some of the properties, yes, they will be excluded. Okay. And once we can clear the cart, it's a smooth sailing from here. We just want to set up those functions, we want to add the functionality. And yes, we will take a look at the action. While it looks like and why we're looking forward to payload. I know I said this already million different times. But since right now, we can modify the state directly. There's tons of ways how you can set this up. Now, I purposely kind of tried to showcase the mutation approach. Where Yes, of course, in these examples for increase in decrease, we can return a new array. But I purposely just found the exact item and then updated the amount plus or minus. And also, of course, you can combine, increase and decrease into one function, let's say you can call this toggle. And, of course, you'll just have to provide here more values, whether you're increasing, decreasing, and that could be your challenge. For now, we just want to focus on a remove item. And the first thing that I want to showcase is the fact that we can access the payload. So whatever we pass in, because in order to get the specific item in order to remove it, I do need to get the ID correct. If you're paying attention in the card item, we did the structure ID. However, we haven't used it here. So this is something that we will pass into the function. Essentially, as far as the remove item, I'll get it from action by payload, because that is the structure. I'll name this item ID. And then I just want to set equal state code items to the new array. Now, I wasn't doing this purposely again, there's tons of ways you can set it up. But in my case, I just thought that filter is the fastest one. So we got state dot current items will filter it, we look for specific item that does not match the ID. And we return that into this car enum, so if the ID matches, so whatever we pass in matches to the ID, then that item won't get returned and in the process will remove it from this array. So let's try this one out. Were in the cart slash, let's set up that remove item. So I'm gonna go here with a move item. And first, I just want to showcase Now, we can access the payload. So first one is the state. So we access the state here, then I'm gonna go with action. And later, I'll showcase how we can structure that. And for time being, let's just look for the action. And now let's think about it. Where do we want to access all these functions, remove items, increase, decrease, and not calculate totals. So only these three, well, we want to get that in the car item. So first, in the cart slice, we want to export that, again, what's really cool, the fact that the name is exactly the same, we don't really need to think about it. And I say, No, it shouldn't be removed items, it shouldn't be removed. And my apologies for some reason, I just keep adding those S's there. Then, let's navigate to the core item. First, we want to import the remove item. So we're looking for a remove item, notice how right away we get that named input. And also we want to get that dispatch. So I just set it up over here, where it will say import, when use dispatch, notice coming from react Redux, then the very top, we're gonna go here with const dispatch. And that will be equal to use dispatch, let's invoke it. And then let's look for a remove button. So now basically, every time we'll click on a button, we will remove that specific item. So let's say here on click, then we do want to pass in the arrow function. First of all, let's say dispatch will go with a remove item. And now let's pass in the ID. So first thing, what you will see, once you click is the log in the console. So let's click and check it out. In here, we see two things. First, we see type. So notice how that is right away already set up for it. Like I said, we no need to do anything right away has cart, and then remove item. So this is the action that we're dispatching. And we also get the payload. Now can you pass in the payload as an object? Absolutely. But if we pass him as a symbol property, then we have payload is equal to whatever. So knowing this, and we can set up the rest of the functionality, where in the cart slash, how to assign action, that payload equal to an ID const. I think one call this product ID, or sorry, no, I'll call this item ID. So const, item, ID is equal to action road. And then let's set up the new value for the state cart items. State again, yes, we're modifying this, we're gonna go with cart items is equal to, and now let's access the old value. Basically, before the update, we can do that with state or items veinlets around filter. And like I said, if the ID matches, the item won't be returned. So essentially, we will remove it from our cart items array, we're going to call this items. And we're gonna go with implicit return where I'm going to say, if item ID does not match the item, Id only then return it from the array. And as a result, check it out, click, we just keep removing the items from our bag. Again, yes, we're not affecting the amount, as well as the total, all of that is coming up. But we shouldn't be able to remove all of the items from our cart, be it with clear cart, or individually by clicking on the Remove button. Alright. Now once we're familiar, we can remove item, and also do the same thing with increase, decrease. Now in order to make things interesting, I already destructured the payload. So remember, we're getting the action object and we're looking for the payload. So in this case, I just structured up in the case of increase gold state card items find. So we get that specific item, in this case, where the ID matches, unlike the filter approach, and then I just want to update the amount. So every time I'll click on the increase button will increase the amount of specific items we have in the cart for this phone or that phone. And hopefully you see where I'm going with this. And eventually, of course, this will also affect the amount as well as the total. And yes, I'll set them up pretty much right away, since the functionality is exactly the same apart. From the fact that in this case, we increase, and in this case, we decrease. And like I said, if you want to challenge yourself, set up a toggle functionality, where you look for one more value, increase, or decrease, which of course is going to be in the payload. And then depending on that, set up the functionality, but for now, I just worry about these two. So we're going to navigate to cart slash, and then right after move item, let's say here, increase, set up our function, say state, like I said, right away, look forward to payload, we'll set it equal to, and when it comes to functionality, we want to go with const. First, we want to get that cart item, the specific one where the ID matches. And we can do that with state cart items dot find, when what's passing the callback function, let's say item, an item ID is equal to payload and pass this in as an object. So it's going to be a load.id. A man, let's increase that amount. So now I'm accessing that one specific card item of the amount property. And please don't confuse this with the total amount. So that's total with all of the items that we have in a cart. When we're talking about this cart item on property, we're talking about this one over here, for that specific cart item. And we'll just say, cart item, mount. So whatever it is right now, plus, or yeah, in this case, the last one, a man, in order to set up decrease, we want to copy and paste, you want to go with the grayish, still going to be a payload. Okay, all of that is awesome, still look for the card item, the difference here is minus one. And then we want to add them, of course, to our exports. So let's say increase, decrease, and we want to navigate to the cart item, we want to import the other two as well. So we want to go here with increase, then decrease from them. And first, let's set up the increase because for a decrease, we'll have to add a little bit more functionality. So let's go with mom button. Let's say on click, we already added dispatch. So we don't need to worry about that one. We just want to pass in the increase. So we're gonna go here with this batch. And inside of this batch, let's pass in the increase. And like I said, in order to make this interesting, I'm gonna go with an ID. Now normally, if you're setting this up as an object, of course, you'll pass in more properties. But in this case, I won't do that. For some reason, oh, yeah, my bad. So I set up the important or wrong place, we add a comma here. And hopefully everything is going to work. Yep, looks about right. If we try this out, notice how again, we're changing this value over here for each item. And again, the functionality here is following where we look for the payload, which in this case is an object. That's why we go here with payload.id, just to showcase that we can pass in more data. And then we're just increased the amount, the same thing we can do with decrease. So let's go back to the cart item. I'll take this entire thing for the unclick. Copy and paste. And now let's go with a decrease instead. So say decrease, again, bass in the ad, that doesn't change. Let's refresh. So we start from scratch. Now notice how we can decrease them. Now the problem is that we're going negative. So I think it's going to make a bit more sense. If we'll check for the amount. And again, we're talking about the amount of specific item, not overall amount. If it is equal to one, we want to remove it since that way we'll have zero items in the cart. And if it's bigger than one, then of course, we just want to run the decrease. So I'm gonna go back to this on click on set up, if amount is equal to one, that means that we're pressing the button amount is already equal to one. And if that is the case, well, we might as well remove the item from the cart. Correct. Let's say remove item. And we'll just pass in the ID. Now we do want to pass the return right after because you don't want to continue reading the code. And if the amount is bigger than one, then of course, we just decrease the amount. So let me go here, let me refresh and notice, I can increase, I can actually decrease. So all of that is working. But the moment I get the amount of one, if I will click the decrease, I'll automatically remove the item from the cart. All right, and up. Next, let's take a look at how we can calculate the totals because at the moment, yes, I can nicely control our cart. But that is not affecting the amount that we have all the way up top. And also, it's not affecting the total. In order to fix that, we'll come up with a new reducer, call this calculate totals, and I went with dysfunctionality. So I created new variables amount in total, then I iterate over the current cart items, and each of them as the amount property. So I just add to the overall amount one, so the one that represents the entire cart. And the same goes for a total, only in this case, I multiply the amount of items that have with the price, and that is equal to the total one. So I set up the loop, I add both of these matters. And at the very end, I just go with state amount is equal to your map. So whatever we created over here, the same goes for total. Now, where do we want to invoke that? And that's a good question. Let's keep on scrolling in the readme, I actually set this one up in the app. So in the app, I will set up a use effect. And that usually will depend on the columns. So use your selector, grab the cart items from the cart. And every time there is going to be some change in the cart items will dispatch the calculate totals, and as a result, both of those values will change in here, as well as in the total. So let's try to set this one up. Let's start by creating the function calculate and then totals, then it's going to be our function or axis, the state as far as the logic, let's go with let amount is equal to zero, and say, no, they have tiny bugs over here, then I want to copy and paste and let's just say total. So by default, it's always going to be zero and zero, then we want to go with state than cart items. let's iterate over, so called for each and last or access each and every item. And each and every item has the amount and all property. And we just want to add this to the total amount. Therefore we'll go plus equals and then item amount. Now when it comes to the amount of money, we want to multiply the price for each item has with the amount of items we have in a cart. So total is equal to and now in this case, we'll go with plus equals item amount multiplied by item dot price. And once we have this one in place, next, we want to set state amount equals to amount that we just set up. And the same goes with total. So let's go here, let's say total is equal to total. After that, we want to export that. So it's a calculate totals. And we just need to set it up in the app. JS. So let's navigate to app J S. And in here, let's grab first the use selector and use dispatch, we'll need both of them. So let's say import, use dispatch use selector. And we'll set it equal to from react Redux. And also I want to get that calculate totals. So let's say calculate totals that is coming from the features. Okay, beautiful. And as far as the logic, well, first, let's grab the card items. And we use use selector for that. So cart items. Now that is equal to use selector let's pass in the function. And let's say here, store is equal to store cart. And I'm not gonna repeat myself, how we can actually do that. And also, we want to set up that dispatch. So const dispatch, matter is equal to use dispatch. Let's invoke that. And let's finally set up that use effect. So let's say here, use effect, man, as far as the callback function. We will invoke this every time there's a change to the cart items. So every time we update something related to the cart items, we will invoke this use effect. Specifically, we want to go with this patch. And we want to pass in calculate totals. So check it out. Now, we still have four here, but I can clearly see my total, what's going to happen every time we'll click on any of the buttons, and all that will nicely display whatever items we have in the cart. Now there's a tiny bug over here. Basically, we need to set this one to fixed, essentially, how many numbers after that, and don't worry, we'll do that in a second. But the goal here is that now, every time we remove item from the cart, or we clear the cart altogether, it will affect the amount of items we have, which will display over here, and also the total. Now in order to fix the bug bear with too many numbers, we just need to go to cart container. And where we have the total, let's go with two fixed. So that's, again, the JavaScript method that we have access to. And we'll say that we only want two numbers after the dots, now, everything is going to work. And just like that, we have calculate totals in place. And every time we'll make some changes to our cart, they will affect our initial state in the cart slash. Alright, and next, I want to set up a modal in a process, we'll create another slash. And we'll see how we can access data when we have multiple reducers. In our store. The first step is going to be creating a modal Jas with the following code. And then we want to import that in the app J S and place it above the navbar. So let's start working on that where first I'm going to create model j is not going to set up any kind of imports. In this case, we haven't set up the slice yet. So we'll just create that component. And as far as the return, we want to go here with a side. And we want to add a class name of modal container. And as set out if you're interested in the CSS, just please look for those classes in the index CSS of and we want to create a div with a class of modal inside of it, let's say heading four with the text of remove all items from your shopping cart. And after that, we want to go with button container where basically we'll place two buttons just to showcase how it's gonna look like go to complete one. And again, we'll display that once we try to clear the clock. So this is going to be the result. So right after the heading, we're gonna go with a div with a class of btn container inside of it, let's place two buttons. First one will be confirm one and the second one will be the clear one type for both of them will be button and class name BTN. And I'll call this confirm BTN. And as far as the text, we're gonna go with confirm as well. And the same deal with the clear one, we just want to change some values around what it's not going to be confirmed is going to be canceled stead. And instead of confirm hype and VTn, we're gonna go with clear BTN. Now we want to go to address, we want to get this particular component. So I mean, I've been try here with the auto import. Let's see, we have Modo. Yep, that worked. And once we save, check it out, this is going to be our model. So we added the component. Now we're just need to set up the logic. All right. Next, let's set up the slice for the model. So remember, we have a features folder. For the time being, we only have one feature, we have the car. But now I want to add the modal feature, which is going to be located in the modal slice. And then we want to set up the functionality, where again, we're going to go with create slash, we want to set up some initial state, in this case it's going to be is open and I'll set it equal to false. Then we want to go with model slash come up with name initial state. And right away, let's set up those two reducers. We're gonna go with open modal and closed modal. We want to export that. And we also want to export modal slash reducer. And in the store, we want to set up another key only in this case is going to be equal to this model, slice reducer. As a result, we'll be able to access to the state, as well as the reducers. All over our application. And the first thing that we'll do is in the app js, will grab is open an OLED display this one conditionally. So I'm going to go to the features, we want to create a new folder. Let's call this modal, then we want to go to New File, and we'll call this modal slash Jas. And then inside of it, we first want to grab the Create slash. So let's go here with create, and let's see whether Yep, gives me the import, then we want to set up the initial state, Mike is just going to be one property. Again, this is just a practice working with more realistic application where of course, there's going to be more features. So we're gonna go here is open. By default, let's set it equal to false, false, and then let's set up that slice. So const, modal slice is equal to create slice, let's pass in the object name, our LAN initial state is equal to initial state, and that's right away, set up those reducers. What reducers we're gonna have, we're gonna have open modal reducer, which is going to be equal to state action. And then we're just practicing as far as the action or not, here's the in here, I just say state is open. So if I want to open a model, what is going to be value? Well, might as well set it equal to true, kind of makes sense, don't you think? Then, let's copy and paste. And now we want to close the model. Now what is going to be the value for is open? Well, let's set it back to false, then we want to export three things, the main reducer, and I'm not going to log it, we already have done that. So export default. Now, of course, we have different object, but the property we want to export, meaning the method is still the same, we want to export the reducer, that's number one. And then remember those action creators, so we're gonna go here with export cons. And now we're looking for open modal, or was modal. And both of them are coming from modal slash, and the actions. Now, in order for everything to work with definitely, definitely, definitely need to go to store. So let's find out where's that sucker over here. And then in the store, now we want to get the model slice. So I have to change some things around this is going to be coming from the model name will also be modal, this is going to be a modal reducer. And yes, of course, the property, I'm going to go with modal as well. So modal will be equal to modal reducer. So that's good. Now let's try it out in our application on a big screen. And at the moment, we're calculating the totals notice, we have already two actions, not only the init. And we also run calculate totals. What I want to showcase though, is that setup just card. Now we also have the model. Now let's utilize that, where in the app js, not only I want to get the modal, I also want to access what I want to access is open. And I want to set this one up conditionally since in second, we'll add all the functionality shown here. Remember, we were accessing the cart. So the only difference is that now I want to access the modal. And I'll say is open is open now will be equal not to the store cart, I'll say store model. And where I have the model will have the conditional rendering, where I'll say is open if it's true. And we then display the model. So let's move it in. And since the value is false, we don't display the model. Now if I'll manually go back to my slides. And I'll say that the value is true. I mean, you're not going to be surprised probably by the fact that we display the model. Okay, awesome. So now let's add that functionality where instead of just clearing the cart, why don't we open up the modal when we click on this button. And then once we get to the modal container, then we'll decide do we really want to remove all the contents, and then close the model or we simply want to close the model. So first, let's start in the cart container. And assignment. Yes, you'll find all of the logic here in the readme were first in the car container we want to get the open model from the model slice Instead of clearing the cart directly, we'll go dispatch an open model. And from there, we'll finish everything in the model, Jeff. So let's start in the cart container. So we have all of these imports. Okay, that's awesome. But we want to copy and paste, and we're gonna get open modal, from the modal slash, open modal. And instead of dot slash, we're gonna go here with modal. And then modal slice, line alerts, keep on moving, I don't think we actually need this important anymore. So we can remove it. And then where we have the clear cart. Now let's pass in the open model, same deal, we invoke it, so that doesn't change. The difference, of course, is going to be that now once we click on clearing cart, we display the model. So now let's navigate there. And let's handle that. So what first do we need over there? Well, we'll need quite a few things. First, we want to get the close model, because regardless on which button would click, I want to clear it, I want to get the use dispatch, I'll need it, since I want to invoke some reducers. And I also want to get the clear cart. So notice how again, we're getting this data from multiple slices, model, slice, and cartilage. And then of course, we'll just set up the functionality. So let's go back over here, let's set up all those three inputs, we're gonna get the closing modal, close modal. And I also want to get the clear cart, where cart. And also we want to get the use dispatch, let's see whether that is going to work. So use a spatula, yep, I have all of them. So now I can remove these suckers. When we want to quickly set up the dispatch, where effectively we just go with us dispatch and we invoke it. And now except functionality, where if we click on Confirm, I want to do two things. Not only I want to clear the cart, but I also want to close the modal. Now if we go with canceled, then we'll just close the modal. So let's go here with button we're gonna go with on click in here, let's pass in the function. And then we're not going to pass in any kind of argument, we'll just go with dispatch, rather than clear cart. That's the first thing we want to invoke. And then the second one looks like some weird bug or Yeah, over here. And the second thing is the closed model. So let's pass this one. And I know I keep repeating this. But I really liked the fact that we don't need to do any of that manual labor, where we need to set up the actions and all that in this case, we simply right away get those functions. And we pass in this batch, which obviously is way less time consuming, and also less chance for errors. So let's do the same thing with this button. The only thing we want to change here is clear cart where we basically want to remove it. So if we confirm that our cart is empty, if our we just click on Cancel, we close out of the model. So that's how we can add another feature to our application. All right, now let's see how we can set up a synchronous functionality with a Redux toolkit. So here's the plan. So I have quarters API, basically an API that serves some JSON data just so we can practice on fetching data. And in the user reducer project, we already work with this URL. So it's caused API and then react use reducer client project, which essentially returns the same data that we currently have in the current items. So use this URL to fetch data, when initially our application loads. And here's the thing, we cannot just simply set this up in our current reducers. It's not going to work. That's why with Redux Tokat, we install another library, the thunk one. From the Redux toolkit, we get this create a sync thunk and rewrite away want to invoke it the result we want to export. So this is something that will require directly in our components. So it's very similar to how we exported the action creators from the reducers. However, in this case, we exported directly Miko, so I'm going to call this get carp items. So we invoke create a sink thunk on it Looking for two things for the action type. So essentially here, we just come up with a name of our action, and second is going to be that callback function. Now, in the following video, I'll show you more options. But the very least we pass here, this function, and this function needs to return a promise. I'm just using fetch to fetch data. Remember, when we go with fetch that, then we return basically, a success response on what catch of course, that's going to be the error. But regardless from this function, we're automatically returning the promise. This is what the callback function is looking for, it's looking for that promise. And of course, you're not limited to the just patch. You can set up all kinds of things in here. But remember, this function needs to return a promise. So of course, if you just stick a sink in front of it, then by default is going to return promise, which is something that we'll take a look at in the next video. And then in the fetch, I want to pass in the URL. So the one that gets me the product. And when it comes to this callback function, it returns a life cycle actions. So if you remember, when we work with promises, we had few options. Promise couldn't be pending, it can be fulfilled and rejected. So where we have the create slush, what we want to do is set up extra reducers property, it's going to be an object. And then in order to access those lifecycle actions, the syntax is like this, where we go with name, what we're getting back, and then dot pending, fulfilled and rejected. And yes, these need to match to the tee, because they are provided by the Redux token, and then we want to enclose this with the square brackets. And then we'll set this equal to a function. So what do we want to do when we're pending? Basically, when we're loading, and that's why we have the state value is loading. And we'll set it equal to true, then what do we want to do if we're successful, this is the case where the data that we're returning in the case of success, in our case, response that JSON is going to be located in the action payload. And of course, we'll log in just so you can see. So once we have successfully data, we want to set these loading to false and card items to the actual payload. And if there's some kind of error, we have rejected option. And in that case, for this application, we're just gonna set is loading to false. And also keep in mind that when it comes to fetch 404, is not an error. So only have this one, if there's some kind of network error. And at the very last, we want to grab get cart items in the app, app component. And then when our application loads, we want to do two things, we want to dispatch get cart items. So the a synchronous function. And then we also want to grab is loading from the state. And while we're loading on display rubbish, once we're successful, we'll set the state car items equal to the data that we're getting back. So let's try this one out where I'm going to go to cart slice. And first, I want to grab that create a sync thunk. So that one is coming from Redux toolkit, then I want to set up the URL. So right after the import, let's go here with const URL. And you have two options, you can either get it from readme or you can just navigate here in the browser. So since I already have it open in a browser, I'll use this approach. So again, this is the URL where we can fetch those products, just like we have in the car Arabs. And then let's keep on scrolling. And we'll go with create a sync thunk, and we'll set it equal to our function, but we want to right away export it. So let's say const. Get cart items. And that is equal to create a sync thunk. And like I said, it's looking for two things. The type, so And here, we just need to come up with a name. In my case, I'm gonna go with Clark Ford slash get cart. And um, so that's going to be my action. And second will be that callback function. And here, let's right away, go with return, fetch. Let's pass in the URL, then dot then. So if we're successful, I want to turn this into a JSON. So say response. Response, JSON. Let's invoke that. And let's also go with catch handler. In the next video, take a look at more reasonable approach how to handle this. But for time being, I just want to get that data from the URL. So let's go here with our log that sucker. And once we are done, we want to keep on scrolling. In the Create slides, right after reducers, the property name is extra reducers. Notice we right away get that suggestion. And like I said, then we get those lifecycle actions. So for every function that we will create, in this case, it is cart items, we'll get those three lifecycle actions, pending, fulfilled, and rejected. And the way we can access that we go with the same name, so get cart items in this case, and then notice right away have those options fulfilled, pending, and rejected. So in my case, I'm gonna start with pending, that is, well, we're still loading. And in this function, same way, we can access the state. And also we can get the action. So action is going to be useful once we get the data. For now, while we're pending, we just want to grab the state, and I want to set the state is loading value equal to what equal to true, correct. So while we're loading is loading will be equal to true, then we want to copy and paste like so just want to add the commerce. So there's no bugs in here. And we want to change these ones around, or instead of bending, normal looking for fulfilled. And in this case, I do want to add another parameter, which is going to be action. And again, this action will contain the result if we're successful. So in this case, if we're successful, we return the JSON response. What I'm going to do is set my cart items so state, and that cart items equal to what action and payload and yes, let's also log in just so you can see where it's coming from. But I can tell right away that there's a payload property, and that's the one that holds those cart items. So let's log the action. And lastly, we also have rejected. Like I said, since we're using fetch, it's only for network errors. And for time being so this equal to false. And also, there's a tiny issue here. Once we have the data, of course, the loading will be false. So we don't need to export this, we're actually in good shape. We already export that function. Here. With export. Now we just want to go to app Jas, we want to grab the function get cart items, we want to invoke it once our application loads, and we also want to check for is loading. So let's navigate to app J S, since we already import the calculate totals from the cart slash, simply want to add a comma, and we'll go with get cart items. And then let's keep on moving. Not only I want to get the cart items, I also want to check for is loading, sorry for loading, then we'll display different return. And then let's set up a different use effect where I'm going to go with use effect. And I'll invoke it only when my application loads. So once my application loads, what do I want to do, I want to dispatch and we'll go with get carte items, and we'll invoke it also set up that return. Or basically, if we're loading, this is what we want to return we want to go with David class loading and then heading one loading. So let's set it up here. If is loading is true, then we want to go with return. Then let's set up a div here. Let's add a class of loading. Man side of it, we're gonna go with heading one on loading that. And once we save for second, we'll notice that loading, and then we get the product. And if you don't believe me, let's navigate to the big screen over here. Let's refresh. Let's check it out. And here we have the panning, which is going to be for at loading one. And we can clearly see our state. And notice how awesome it is in the Redux dev tools where you can clearly see your actions. So what actions were dispatching and what is the state of that time and we can even see the difference. So basically, if I'm going to go here with fulfilled, notice this is going to be the difference. So in cart, we basically get this is loading, and we'll set it equal to false and also in the console. You can see what we're getting back. Remember I said that once we log Over here in the cart slash, we are logging the action. So what is in this action, it is a payload and lots of data that we're getting back. So we have this array of four items, we set here, state cart items equal to the payload. So again, something we can definitely double check over here. So if I go here, with state, notice we have fulfilled, for example, this is going to get me those car items, those four cart items, and one more thing that we can actually do is go back to the cart slice, and set this equal to an empty array. So the cart items and that way, you'll clearly see how we can change this once the data gets here, asynchronously. So let's navigate back and let's refresh just so we are on the safe side. And if we go right now with action fulfilled, and if we take a look at the difference, now notice two things. First of all, is lowering change from true to false. And also notice how we switched the car items. So initially, it was empty array. And now essentially, we get those four items. And then all our functionality still works, we can clearly see that in our actions over here. But now we're getting this data asynchronously, once our application loads. All right, and lastly, I just want to showcase what options we have with the callback function. Because in our previous example, we just looked at the most basic setup. So now let's go over the more complex one. And don't worry in this video, you don't have to type along and in fact, we won't use any of this extra data. In our current application. The goal is to simply get the gears in your head turning and showcase large amount of options we have. And first, what I want to do is install another library, the HTTP library by the name of Axios. Because I do want to showcase how essentially, we can return a value for the error. And since fetch is not responding to 404, basically, for fetch the 404 errors are not errors, I actually want to use the app shows instead again, if you don't want to do that, you can just sit back and relax, where I'm gonna go with npm install Axios first, then we definitely want to spin up the dev server, of course, npm start, I'm gonna close this one, then we want to navigate to cart slice, I think I can remove the items, we won't need it anymore. So X years from X years, let's keep on moving. And before we do anything, like I said, we can create this function right away as a sink, which essentially just means that will right away return a promise correct. So go here with a sync. And that also means that we can await so we can set up more logic. So let me remove all of this code here. And let's just go with try and catch right away, since we can also do that. And then let's wait for that response. So I'm going to say here, const. And then response is equal to await. Now I'm gonna go with X heroes, and then I'll pass in the URL. And if we're successful, where do we want to do, we want to return that response. Again, keep in mind, we are returning a promise. And yes, we're handling that in the actual reducers. So none of this functionality changes right now. We're just switching right now, our create a sink thunk callback function to a sink where we're using Axios. Now, once we save, we will get some errors in the console. Don't worry about it. The reason for that is because when it comes to Axios, the data is located in the data property. And just to showcase that. Let me go here with log and sponsz. You'll see in the console. If you scroll up, you'll notice over here, this is what we're getting back. And essentially what we want to do, we want to pass in this data property down to these lifecycle actions. So we're talking about this one over here. So let's scroll up. And we'll go here with return. And let's go with response. And then there again, this is just because that's how the response is structured. So once we save, notice show, everything worked correctly, where again, we're getting those items. And if we take a look at the action, it's still the same thing. We're getting this payload and the payload is that array So that's the first thing that I want to mention. Also, we can pass here, the arguments. Now, what does that mean? Well, in our case, we're not going to use that. But we need to imagine that, let's say, we're going to be setting up some kind of functionality. And we do want to pass here, the value, let's say whether that is user or some kind of parameter, or something. So in this case, I'm just going to say, random. And if we want to access that, again, in our case, not going to change anything, but if we want to access that, this is going to be the first parameter. So in my case, I'm gonna go with name. And let's simply log that will clearly see that we can access that, again, not something we'll use in our application. But it's very, very important because there's going to be applications, where, of course, this is going to be important. The fact that we can pass something here from our component, and we can access it in our create async thunk. That's the first thing that I want to mention. Now, second, we also have access to thunk, API again, you're gonna name it differently. But I mean, common convention is calling this funk API, which gives us even more options. Now, what am I talking about? Well, first of all, let's log something, let's go with log, then let's access funk API. And you know what, let's just log the entire thing. So you know what, there's quite a few things here in the console. So let me remove this action. Basically, I'll comment this one out for your reference. And also, hopefully, it's clear how we can pass the parameters from the components, that's clear. But then check it out, we have this somewhat giant object with a bunch of useful things. So here's the thing, we could get the state. Now what's interesting, we're getting the state of the entire application. And this should get the wheels turning in your head. Because that means that we can get any values from rest of the features. So let me quick click quickly showcase that. So I'm gonna go with log and then funk API. And let's go with get state and let's invoke it. And in the console, I have both, I have the values for the cart, as well as the model. So imagine if you have, for example, a user feature where you're setting up the user, yes, when you're setting up your a sync action, you can actually access it. So I can set up the user in a different feature. And I can still access it with the help of the stunt API, which is very, very, very powerful. And also, what's interesting. Well, we can dispatch. If we take a look at the object over here, notice, we have this dispatch option. So what we can dispatch well, for example, let's open up the modal while we're fetching. So let's try this one out. We're right after the get state and all that mean, go here. And we're gonna go with thunk API. We're gonna go with dispatch. And now we want to pass in open and modal. Again, something that is not even in our slice, and check it out. And as I forgot to add here, the parentheses. Notice, even though this reducer is not even in this feature, we can still access it with thunk API. And I know you're sick of hearing this. But this is extremely powerful. Because we can do all kinds of functionality in the Create async thunk. And lastly, what I want to showcase is how we can return a specific response because at the moment, yes, we have catch and we are basically getting the error. But normally from the API, you will get some kind of specific message. So first of all, how we can pass this through again, we're going to look for some KPI and we want to go here with the return first of all, and then the property or the method you're looking for. So let's go here with thunk API is reject with valid. So in this case, I will hard code this will keep in mind that normally, with Axios is going to be located in error dot response. So in here, let's say something went wrong, like so. And then let's keep on moving. Let's keep on moving and where we have the rejected. Now we can look for that action. In our case, again, we don't have any error values or mistakes or nothing like that. But let's just log whether we can see that action wherever we can see that everything works. And since we are using actually ocean now I can mess up the URL. And for Axios, it will be an error. What that means, well, we will trigger this and will basically pass this value down to our rejected. So let's save it. And then notice in the console, we right away see this log, we have this payload where we have something went wrong. So for example, if we're getting some kind of error from the API, it's going to be located an error response. And we can nicely pass this down using thunk API, and then reject with the value. So that's how we can set up asynchronous functions with Redux toolkit. This concludes our tutorial. Hopefully everyone enjoyed it. And I'll see you next video.
Info
Channel: freeCodeCamp.org
Views: 239,286
Rating: undefined out of 5
Keywords:
Id: bbkBuqC1rU4
Channel Id: undefined
Length: 110min 42sec (6642 seconds)
Published: Wed Apr 20 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.