Using React Context
In this lesson, we're going to implement React context to centralize state
Using React context#
Basket is something we want to update from any part of the application. A real world e-learning application has plenty of pages, and from any page, you can add an item to your cart and you would see the number getting updated, as we know passing data is only possible from parent to child, not the other way round. To make our basket data accessible from any page, we can use props which will be quite complicated as data will have to go through the components which don't need it. We can either keep it to the topmost element such as the
App.tsx file and pass the data to the children, or we can use the state management system such as React and Mobx, which we are going to do soon. But what if you don't have a huge requirement for centralizing the state? In that case, using Redux can be an overkill.
Well, in this situation, react context can come to the rescue. It comes with React and does a pretty good job when it comes to centralizing the state, so let's see how to do that. Inside our src folder, we will need a new folder called
context. Inside, we can create a new file,
StoreContext.tsx. In simple words, we are creating a component which will be a wrapper for our application. Any data or methods made in this component will be shared to the entire application.
We'll start with the interface which will have everything we need in our StoreContext. First of all, we need a basket which will be of type Basket so we can import it from our models. This can also be null so we can use a pipe followed by null. We also need two methods, setBasket and removeItem; setBasket item will accept basket as a parameter and will return nothing so we can write void, while removeItem method will accept a courseId and return void.
Now we will create method to store our storeContext, so let's create export const StoreContext, which will be equal to the createContext method that we can import from React. We can give it a type which will be StoreContext value. It also takes a default value which is right now undefined so we can again use pipe to make it undefined.
We can create a customHook now and we can call it useStoreContext. This will return everything we have in our StoreContext. For this, we can create a new variable context, and we will use another hook from react called useContext. This takes the value of our context which is StoreContext. We can also put a condition which checks if the context is undefined. In this case, we do not want to return the context, so we can throw an error instead, which can say the Store context is currently undefined. Finally, we will return the context.
We're not done yet; we now want to create a storeProvider, as parameter. All we want to pass are the React components. Since our StoreContext is going to be the wrapper, everything inside can be considered as children, so we can simply write children and give it a type PropsWithChildren which is provided by react and we can give it a type any.