Hello everyone, my name is Piyush and welcome to my YouTube channel In this video we are going to see what is React Redux and we are going to understand React Redux from the basic to the advanced level and this was the most demanded video on this channel so I got a lot of comments that I need a video on React Redux so in this video we are going to understand from the basic what is React Redux what is the problem that React Redux is solving and we will also code React Redux in React so let's get started and lastly we are going to see what is react redux toolkit so watch the video till the end and if you haven't subscribed yet then please hit the subscribe button and let's start with the video so first of all let's understand what is the problem so what I have done is I have taken a wireframe of an e-commerce website to understand the problem so here if I show you, we can see that there are many components like we have a navbar above After that, we have product images here. Then we have this add to cart button. And after that, a cart is showing up here.
Now, what is our desired behavior? When I click on this add to cart button, then my cart on the navbar should be updated. Correct? So, when we talk about a real world, we have a lot of components. Correct?
And due to the change of any one component, Other components'data also changes. For example, if we add to cart, basically my cart is also getting updated. Here also, the quantity will be updated. So, what happens is, an issue in such complex UI becomes an issue in managing the state.
When you have a very complex UI and there are many components, then taking the correct data from every component is an issue. So, to solve this problem, if we don't have redux, then we use prop drilling. We have an app component, in which we have a state of items. After that, we drill a prop component in which the app component reads the product page.
When we click on the Add to Cart button, we need a handler function which we pass to the parent. For example, I have the Add to Cart button. What does the product page do? First, it gives this page that add an item.
Then this page will send you the item. Then the app will update these items. Then these items will be drilled down again and will go to the cart.
Then it will go to the cart. the more complex the UI will be, the more the prop drilling will increase. What is the problem with this? For example, the cart component is under pages, right? Suppose, if I want to add this cart component to the app, then I will have to change its props.
So, refactoring is not an easy task. So, to solve this particular problem, we have Redux. So, what does Redux do? We will change this state to, We will not keep it in the app, we will keep it in our redux store. Correct?
So, what will happen is that our prop drilling is over. Right? Because our state has gone to our redux store after getting up from the app. I will explain what is a redux store in the coming slides.
I will explain the whole architecture. But for now, understand that there is a single source of truth, a store, in which we keep all our data. Okay?
What did a cart do? It subscribed. Whenever there is any change in our state, the cart will update itself.
And the product page can add to cart in our items. So, as soon as we add to cart on the product page, this state will be updated and the cart will automatically know that something has changed. Because our cart has subscribed to it. So, the prop drilling is over. Now I can keep this cart component anywhere without worrying about the prop drilling.
Redux store has an overview of what Redux does Now let's understand its architecture Because Redux's architecture is not that straightforward We just put items in a store and retrieved them from there We are going to understand Redux's architecture through this diagram So it is very easy, there is no complexity So let's understand each component one by one So first of all, we start with UI layer What is UI layer? Basically, what we see on the web, we call it UI layer So, in UI layer, I have created a button. For example, let's take an example. I have a button.
So, let's say this button is our add to cart button. So, from the point of view of Redux, when it will be clicked on this button, then what will happen is that we will call a function. Correct?
We used to do this. What this function will do is that you cannot directly update the state in the store of Redux. Okay? You cannot directly update the state in the store of Redux.
What you have to do is that We have to dispatch an event. What is an event? In this event, we will tell what we have to do.
For example, when I click on the Add to Cart button, what can be our event? I have to add an item and I can give its price and item ID. So, this will be our event.
Add to Cart is an event. This event will be dispatched and will go to Redux's store. Okay? Now, what will the store of redux do?
It will not update its state directly. What will the store of redux do? It will dispatch an action on the reducer.
Now, what is this reducer? Basically, what we do is we create a function in the store which we call reducer function. What this reducer function does is it reads our event and based on that event, it returns a new state. Let's understand an example.
If we have a counter app. Let's say our current count is 1. User has clicked on increment. Then what will happen?
An event will be dispatched of increment. In which we will have value of plus 1. So what will happen? As soon as this event will come to reduxStore, reduxStore will put it in reducer.
Now reducer will see what is the increment of event type. And what is the current count of the last state? 1. So, what will this reducer do? By doing 1 in 1, 1 plus, because our event is of increment, it will return 2. Okay. As soon as this reducer function, which we have written, returns 2, then this state like 2, will go to our reduxStore.
So, now what is our new state? 2. And as soon as reduxStore will be updated, whatever will be updated in the reduxStore, then our UI will be automatically updated. And what value will we get here? 2. Next time when I click this button again, an increment button will be dispatched again It will go to the redux store What will the redux store do?
It will give this 2 to our reducer What will the reducer do? It will do 1 plus in 2 because our action is increment And what will it return? 3 This 3 will go to our redux store And this 3 will automatically appear on our UI So that's how our redux architecture works, okay? So it is very important to understand the architecture of redux Because we We don't update anything directly in the Redux store. Our job is to dispatch events.
Events go to the store. What happens in the store? What does Redux do? It calls the reducer function.
And whatever the reducer function, based on that event, whatever it returns, it keeps it in its store. So that's how Redux's architecture works. So now let's understand it with an example.
We are going to code it. And to code it, we make a counter app. Basic.
So that we understand Redux. Let's see if we can understand it. how Redux works.
Okay. So I am going to do a web-based IDE on Code Sandbox. So in this IDE, we are going to make a counter app.
Basically, it is going to be a very simple app. We will have an increment button, a decrement button. What we are going to do is we will keep our count in our Redux and when the user clicks on increment, we are going to dispatch an increment and when the user clicks on decrement, we are going to dispatch a decrement event.
update the store and see how our UI is going to be updated so let's start coding it first of all, I have created a default react app first of all, we have to install a package which is named react-redux so this is the package named react-redux we have to install it so as you can see react-redux is installed at version 8.0.2 so let's start coding it So, first of all, I am going to create a button here. Ok, button increment. So, this is my button which will work as an increment.
So, here is this button. After that, I am going to create another button. Ok, button decrement. Ok, so this is my button decrement.
And I am going to create a component here which will show my count. So, let's go to files. and I'm going to create a folder under src, components ok so what will happen in this is that I'll have a count component so I can say count.jsx so what we can do here is import react from react and after that I'll name this component counter ok and what I'll return in this is for now we'll return a div from here ok and in div let's say we have an h There are two tags.
And for now, we will make the hardcode 0. This value will be stored in the future. And export default counter. And what we can do with this counter is that we can render it here.
So first of all, we will import it. Import counter from components count. And what I am going to do with this counter is render. So we will render the counter.
So now what I have is 0. Right? So, now what I want is that when I increment, then the value in my redux store, now we are going to make a store, we don't have anything, so we will increment this 0, 1, 2, 3, and if we click on decrement, then what will happen, this value will be decrement. So, first of all, our architecture, first of all, what we do is that we make a store of this component, we made a UILayer, we made a button, we are going to make a handler function later, so first of all, what we do is that we make a redux store. So how are we going to make that? So what I'll do is, I'm going to make a folder in the files called Redux So all the Redux based code will go in this So let's make a file in this, store.js So what is this?
It's a store.js file So we made a store.js file in which we are going to make our store So to make the store, we need to use another library, that is Redux So we had installed React Redux, I'll tell you why And we need to install Redux Now what I can do, we have to import something from redux And we are going to import createStore function Using this function we can make a store So I will make a store, I am making a variable store And I will set it equal to createStore So this made my createStore So, my create store is ready. And now what I can do is, we have to give access to this store, our app. So, how can we do that? Go to index.js file. So, what we have to do here is, we have to import something from react-redux.
And inside this, we have a provider. Now, what is this provider? So, if you haven't seen my context API video, So I would recommend that you go and watch that video first And for better understanding, it's an optional thing But you can continue it from here if you haven't watched it So what I'm going to do is, I'll wrap myself in this provider So in this provider, I've wrapped my app component And we'll pass our store in it So what I can do is, I can import this store which we've just created So it's in our Redux store So I imported the store from here and I passed this store to it.
So now my app is wrapped in the provider and I have access to the store. So this is our store, basically there is nothing in it. So what we need is reducers.
So as you can see we are getting an error because we did not give any reducers. So we have to make some reducers. Basically we want one reducer which will handle increment and decrement. So what I can say, I can say const reducer.
So what is this reducer? This reducer is a basic function which has two parameters. Number one is state and number two is action. Now what we will do is Basically, what is state? The state that is running right now Like I told you that if it is 1 for the first time, then it will return 1 And what is action?
That the user has incremented or decremented So, let's do one thing Let's put the default value of state as 0 Okay? So, what is the default value of state? 0 Now, what we will do is Let's put a switch Okay? A switch case We will switch to action Okay? Now, see what I am going to do If Let's put a case Okay?
If Basically, we are going to switch to action.type If the user clicks on increment Then what I will do is, I will say return state plus 1 What I did is, if the user does increment Then what I have to do is, add 1 to state Let's take a case of decrement So what I have to return is state minus 1 And in default case, what I do is, I will return state Means, if the user didn't select anything from these two then basically, 0 will be returned. Now, what we have to do is, basically, pass our reducer function. So, how can we do that?
I can say reducer. Okay. So, what happened is, I passed the reducer function inside it.
So, now my store is ready and you can see increment and decrement are coming. But obviously, it won't work now. Because, what we have to do is, see, we made reduxStore, we made reducer.
Now, what we have to do is, we have to make a handler function which contains events to dispatch. Now how are we going to do that? See what I'll do. I'll go back to my app.js.
Okay. So first of all, what am I going to do? Here we have to import.
Okay. Import something from react redux. In this we have a hook called use dispatch. Okay. We are going to use this hook to dispatch actions.
So what I can do, I can say const dispatch equals to use dispatch. So, now by using this dispatch, I can dispatch the actions. So, let's do dispatch. So, what I will do is, on clicking on the increment button, basically, if we click on increment, then I will say, do this work, dispatch.
What dispatch do I have to do? So, I will give a type in dispatch. What will be the type?
As you can see, what we did here in the store, we did action.type increment, we put a case. increment, similarly what I will do is on click I will say dispatch what to dispatch what is the type of action, copy it from here decrement, so now what will happen when I click on increment, it will increment in the store, when I click on decrement, it will decrement in the store. But obviously our counter is not getting plus or minus because if I come to my components and count then we have hardcoded 0 here. But where do I have to bring this value?
From the store. So to bring the value from the store, we have a hook, okay? That comes from react-redux, okay? Whose name is useSelector. UseSelector is used to select something.
Okay? So what I can say, I can say const count equals UseSelector And what we are going to do in this is We will return our state correct and I can remove this count and render my count so now what is happening my count is 1 if I click on increment then what is my count? 2 then count 3 basically count 4 so let's understand what we did first of all what I did if I go to app. let's start with architecture first of all UI layer which is very simple we didn't do anything special in UI layer we just made 2 buttons increment, decrement and we made a counter.
This was a UI layer. On the click of that, we are dispatching something. What are we doing?
Dispatch. We are dispatching an event. In which we have typed increment and typed decrement.
Okay. From where is this dispatch coming? We have a hook by dispatching use.
What it does is it dispatches an action to our store. Okay. So basically this event is dispatched and goes to redux store. Okay. Now what will the store do?
It gives this event to the reducer. So we have made a store here, in which we have a reducer. So as soon as the user clicked on the increment button, then it was typed, as soon as we click on increment, then it was typed increment. Correct? So that increment came to me here in action.
Okay, I got increment on action.type. So what I am saying is, whatever state is running on increment, which is 0 for the first time, what I did in that is, I did add 1 and returned. automatically whatever will be returned from here, that value will go to our store. And similarly, in the case of decrement, I did state and whatever new value was, means after doing minus one, that too will go to my store. So that's how I can change values in the store using dispatch.
Now how to retrieve value from here, right? How to read value? So to read, we have a hook, useSelector.
Okay? Selector is different from name, to select something. So what I did, I said useSelector. In useSelector, we have the access of state. And I returned the state.
What happened with useSelector? State. And what I did?
I said return the state as it is. And I named it count. And I rendered the count here. So as soon as I click on increment, increment goes to the handler. Handler dispatches.
Redux store gives to reducer. What does reducer do? Increment it and give new value to the store And by using useSelector, our UI will be updated So this was simple React Redux But in production, this kind of work is never done Because this is not the correct way of doing things in React Redux in the production So in production, a thing is used which is called React Redux Toolkit This is a very powerful library, React Redux Toolkit.
And it makes a lot of things simple. Like you must have seen what we did now. We made a store first, then a reducer basically.
Right? So, it makes those things very easy and automated. Okay? One more thing to note, when you go to the store, you will get a warning here.
Correct? What is this warning saying? That we recommend using the configureStore method at the rate Redux JS Toolkit Package. That means Redux itself is saying that don't use me, use Redux Toolkit.
So this was only for the understanding purpose that how does the architecture of Redux work. In the real world applications, what do we always use? At the rate React Redux slash toolkit. So now we are going to start React Redux toolkit and how you can use toolkit.
So for that, I made a new project. Okay, a little bit of e-commerce type. I'll run this and show you what's in it.
Basically, what's in it is, it has products, okay. I've made a product.json file. Okay, this product.json, which has all the dummy products.
So, as you can see, each one has some price, right. And each one has some name. Images, like dummy images.
So, what we want is, as I click on this add to cart, then our cart, basically the total items, which is 5, should be updated. And whatsoever, is our amount okay so that should also be updated accordingly so we are going to use this we are going to work on it now this is just a dummy product okay nothing is working by clicking anywhere so we are going to code this thing using react redux toolkit okay so let's see how we can use toolkit in our react project and this particular code I will give the github link in the description so you can see the description for this whole code okay so let's code this First of all, we have to install dependencies. So I'll say npm install. First we have to install react-redux. And we have to install this toolkit.
So how can we do this? We have to say at the rate react-redux.js So when I press enter, my react-redux and redux toolkit will start installing. And that's done.
So let's do an npm start. So this will reload my page. So first let me tell you what I have done so far.
I have made two components cart and product. There is nothing in cart. I have just hardcoded the values. Total items 5. And in product, it is a bootstrap card.
In props, we have image, product, name and price. And I am rendering it in app.js. So I am reading this product from this JSON file. So here we have this JSON file and what I'm doing is basically looping over it. I'm mapping over it and I'm rendering a product.
Now, the working of add to cart is going to be done using Redux toolkit. So let's see how we can make store in toolkit and everything. So the first step is to make a store, correct? So what I'll say, I'll make a new folder here named as Redux. same as we did earlier, let me zoom in so in this redux, first of all let's make a file store.js so to make this store, we used createStore method and we imported that from redux but what we are going to do here is, I'll say import something from at the rate reduxToolkit and in this we have a function called configureStore and what I can say, I can say export const store equals configure store and what we do in this is we have some parameters like reducer, devtools, enhancer, middleware and all.
So in this we have a key reducer in this we are going to keep our reducers one by one. So now we don't have a reducer so we are going to make a reducer and we are going to keep that reducer here. In redux toolkit, like in the last video in the last section what we did was we made a simple reducer right.
which was pretty simple. This doesn't happen in toolkit. In toolkit, we make a slice.
For every feature, there is a slice. Now, what is this? This is our cart, correct? So, what I will do is, look carefully, in redux, I am going to make a folder called slices.
Okay? What is a slice? Basically, suppose there are many features in your app.
Like, there is a feature of a cart, let's say there is a feature of a chart. So, you can make a slice of each feature. Okay? So I am going to give it a name, let's say cart slice.js. Okay.
So all the slices that will be made in this will be created by cart. If it still seems a little confusing, then it will be clear now. Let's code once.
So I will say import something from at the rate redux toolkit. In this, we have a function called create slice. Not this, create slice.
So what I can say, I will say const cart. Slice, okay, equals to create slice. Let's give a name to this slice first, okay. I'll say name, let's say this is my cart, you can give any name. What will be the initial state?
Initial state I'll say is an empty array, because what's going to come inside it? Items are going to come. So I've given an empty array, okay. And inside this, we're going to make our reducers. Okay, so here we'll have reducers.
So what can be a cart's reducer? What can be the first reducer? to add items in the cart. Right? So I'll say, add item.
Okay? Add item, which is a function. Okay? In this function, what we get is, first, we get state. Okay?
What is this? State. And the second one is action.
Okay? So what I'll do is, our state, basically, what is this? It's an empty area, by default. Action, whatever the user payload, center, etc. is, will come in this. So let's say, when we, If we call this addItem, I will say state equals to So first I will add the items of the previous state And I will push the new item in it Correct, I spread out the old items in the state And added the new item in the last OK and what can I do with this?
I can add it. Correct? And let's do one thing, let's export this card slice from here.
Not like this, not like this. So how we can export? I have to say export default card slice dot What do we have to export?
We have to export reducer basically. We have to export reducer. Correct?
So I'll say card slice dot reducer. So now see, what I can do, I can go to store. Okay? Now I'll import it.
I'll say import cart reducer from. slash slices and cart slice and what I will do is name it cart and this cart reducer so what will happen is that my cart reducer is ready one of our cart reducers is ready and let's try to access this using use dispatch and use selector so the first step is to go to index.js and what we have to do is import provider right so those things will remain same react redux from this we have to import the provider and we have to wrap this provider here so this provider will come here and what we have to give in this is store correct now from where will our store come which we have made by configuring store so from dot slash redux slash store so what is our store in this and what we will do is pass this store in this correct so what happens with this my whole app has got access to store Now let's see if I am able to access these items. Let's try to show this.
First, let's do the work of the selector. So where do I have to use the selector? I have to use it inside the cart. So what I'll say, I'll say, import something from from react-redux, okay react-redux, from here we will do useSelector, correct? So what I can say, I can say const items equals to useSelector, okay?
In this we have state, and let's do one thing, return the state as it is, and let's log items to console.log, so I'll say items, items, okay? So let's see what's coming in our console, so if I do an inspect here, so what's coming in items, an object is coming, okay? Open the object, and we have a cart here. Where does cart come from?
If I go to my store, I had given a cart name here. If I make it cart1, then we will also have cart1. Correct?
So we will make it cart again..cart And what do we have here? An empty array. If we had an initial state, let's say I go to my cart reducer. Sorry, not like this. Slices, cart slice.
In the initial state, let's say I have a... So let's say I put a value here, ABC. Okay.
So what I have now is cart and initial state is ABC. So that's how you can access the state, correct, by using useSelector. Now what we have to do is, basically, we have to use this addItem from here. How can we do that? See one thing, I'll say export const brackets equals cartSlice.actions.
Now, as soon as I come here and do that, I'll say like control space, then I automatically have an ad item coming here. I have exported the ad item that we made here. Now see what I can do.
I'll go to app.js. Okay, in this we have a product. In product, we have a button, add to cart. So, I want to whenever I click on this button, I want to run that action, add item.
I want to dispatch it. So how can we do that? First of all, I'll say import from react-redux So we have a hook in this useDispatch So I'll say const dispatch equals useDispatch So when we were using simple redux, this one, what we did was we made an action ourselves dispatch type increment and decrement, but in redux toolkit we don't have to do this Redux toolkit does this automatically.
So what I have to do, I'll say onClick, okay, pay attention to this, onClick, I'll say arrow function, dispatch, okay, what do we have to dispatch? We have to give action in it. Where will we get that action from?
So the action we just exported, we will import it, okay? So I'll say import from, import something from, uh, I'll go one directory back, redux slices, card slice. In this, we have add item, correct? So what I'll do is, I'll put this add item in this dispatch. Okay?
Now let's see what's happening in our app. So, let's ignore these warnings, okay? As I click on add to cart, okay?
So we didn't get console.log. Let's see if we're doing something wrong. Add, dispatched add item. So what will add item do?
basically it will add the item to the state we didn't send the payload so we have to send that, we forgot to send the payload so addItem, this is the function addItem we have to send the payload in this so I'll say so we forgot this so we do one thing in this, we send the product's name which is props. props.product name we will send its price which is props.price so now we will try again click on add to cart let's do a refresh add to cart we didn't get items right ok we did a mistake here we can't equal state what we have to do is state.push we have to push in state action.payload So, we have to push in the state. So, as I do add item. So, as you can see, there is an item in our cart named and price. So, let's add this item to cart.
So, as you can see, we have two items in our cart. That is this name and this artick. So, we made a mistake.
First of all, we were trying to mutate the state. State is immutable. You can't change the state. So, we have to push in the state. state.push action.payload so this was a mistake that we did and I'm sorry for that so after doing this, what's happening is as soon as we change something, our selector gets activated and it automatically updates our cart now what we have to do is display items here so how can we do that?
if I go to cart, we have items I'll say instead of 5, I'll say items.length correct? items.length length, so what will happen now, what are the total items, let's refresh it not like this, items.cart, basically it was cart.length, right so now how many items do we have, we have 0 items so let's add this, I have 1 and let's add this one, we have 2 let's add this too, so we have 3 and similarly what we can do, we can calculate this too, right, total so how can we calculate total I'll say, okay, so what I'll say, I'll say const total equals, so I'll say items.cart.let's do a reduce here, reduce function. So what happens here is we have two parameters a and b, I'll say a plus b.price and initial value is zero.
Simple javascript stuff. And what I'll do here is I'll display total in my total. So let's refresh, total is zero, items is also zero. So, let's add this $199 thing. So, now I have items, 1 and what is my bill?
$199. Now, let's add something of let's say this $195. Okay, let's add this.
So, as soon as I add this, my total is also getting updated and my item count is also getting updated, which is good, right? Now, see one thing, what we did here is we selected use, by doing use state, right? But, there is a better way to do this in Redux Toolkit, correct?
So, what you can do is, You can go to your slice. We can make a selector here. We have a function named as createSelector.
So I'll say cost getItemsSelector. I'll say, what we'll do is createSelector. We have two parameters in it.
In the first parameter, we'll return our cartState. We took the cart from our state. We have returned the cart from this store.
In the second, we will return the state only. So, what will happen with this? I can select the items with this. First, we have returned the state.cart which will return me this.
Correct? And after that, I have returned the state as it is. And I will say export. Now, what I can do is, I can import this selector here. Okay?
I will say import. Import, yeah. From.
One directory back. Redux slices card slice or is condom. It was guy I got get item selector Man directly a custom instead of like doing this.
I'm is going up and down. Okay, I'm a G dot cart. He's a root me Correct dot cart. He's root Q me because many of us could y'all have the LED now see when I refresh Let's see. Yeah, we're saying he can't get a R2 car 296 one which is correct Oh, it's given me an egg or item part.
Which is correct. It got item card. Yeah, which is correct and it's working perfectly. So that's how you use Redux toolkit. Now there's one more thing that I want to tell you, which is a really handy feature.
If you go to store, here we have a feature called DevTools, which you can set it to true. It's default true. What will happen is that I can see my state here. So now my state is empty.
As soon as I do add to cart, I clicked on add to cart, so see what happened, inside cart, This is our name. Add cart function is running. In which this payload is gone. This name and price. So if I click on state here.
Just a second. This one. So this is telling us what actions we have dispatched. Let's say we dispatch one more.
Dispatch 2-3 actions. So if we click here. So as you can see we have 2-3 items added.
What is the benefit of this Chrome extension? This is basically a Chrome extension. So what you can do, you can go to google.com and you can say react-redux-chrome-extension this one and you can install this extension. So if you are working in Redux, this is a good debugging tool for Redux.
What is the benefit in this? First, I can see my state, right? What has been updated? Like there are four items.
So these are the four items. Let's say I want to jump back. So what can I do?
Let's say I want to jump back here. And so as soon as I click jump. See, I came back to the previous state, right?
And then I say jump here, so I can jump like, as soon as the state changes, I can jump back and forth. So this is a really really really great extension, okay? So you can use this and you can even see what payload was dispatched and what got dispatched.
So this was all about React Redux and React Redux toolkit. I hope you liked the video and you must have understood React Redux toolkit. So see you in the next video, until then.
Bye-bye, take care and do hit the subscribe button.