Context API(>React’s version 16.3) — The Context API provides a way to share data between components without having to pass a prop through every level of the component tree. Context API is not a total replacement for the lib like Redux or MobX or any other state management library.
Let’s consider a scenario to understand the prop-drilling problem and how Context API helps us to overcome it.
We have a state called Language defined in our App component which we need to pass to the Child Component 2 & 3 from the parent component. In order to pass Language props to Child Component 2 & 3, we can pass it through intermediate — Child Component 1.
As you can see in the below image how the props are passed on to the lower-level components. Child Component 1 doesn’t need the Language Props but still, we are passing it so that it can pass it to the Child Component 2 & 3. Child Component 1 is acting as an intermediate component to pass on the data to the lower level.
This method is a good option until we have a few levels to pass the props to the components. But if in case we have a large number of levels or more props to pass on to the lower level than it will be difficult to handle and inefficient. Passing on props to each level is called Props Drilling. In order to overcome this issue, we can make use of the Context API.
Context API is more utility when we want to keep shared data at the global level for all components within the application like User Auth Info, Language, Location, or Cart, etc.
How to use Context API?
Context API has three major building blocks
React.createContext function to create a context object. When React renders a component that uses this Context object it will read the current context value from the closest matching provider.
const contextObj = React.createContext(Val);
Val argument is not mandatory. If we need to pass any default value while defining the context we can.
Let's create a simple react project to understand more about Context API.
npx create-react-app contextapi
I have created the following folder structure as shown in the image. It’s always a good practice to maintain a separate folder for each logic you have in your project like I have created a separate folder for components and context.
let's consider a scenario where we need to pass location-based info(currency, timezone) to the child component.
I have created three child components under the component folder namely Header, Body, Footer. We need to share common data between all three components. In my case, I need to pass information like Currency and timezone to the child component.
Now let's create a context folder and start writing our context logic in CurrencyProvider.js.
const CurrencyContext = React.createContext();
I am creating a Context object using React.createContext. Every Context object comes with a Provider and Consumer component. Provider allows consuming components to subscribe to context changes.
The Provider accepts a value props where we can pass our data to the Consuming Component. A single Provider can be connected to many consumers Component. Whenever Provider Props is updated all-consuming Component connect re-renders.
Now let's call the Context logic into our app Component.
In the above code, you can see I am importing the CurrencyContext and I am passing it as the parent component for all other components like for Header, Body, and Footer.
We have created the Provider. Now let's look at how we can make the child component
We need to import the CurrencyConsumer from the CurrencyProvider and the consumer component in our render function. The Consumer Component expects a function as its children prop that will receive the value from the context function.
The final output of our project.
Context API helps us to share data between different Components without passing Props. You can get more information from React Website. We can make use of context in functional components as well using useContext.