useContext Hook in React

Learn via video courses
Topics Covered

Overview

When we start making React applications, we have to share data between multiple components from the Main Component with the help of props. Passing data from a Main component to a sub-component is straightforward when only a few levels of components are involved. At some point in your React app developments, you may have needed to pass data to a number of components. Doing this via props can be tedious and repetitive, making it a perfect candidate for useContext React.

Context

Imagine you have a React app with single parent component containing many layers of child components. Now imagine passing data from the top component to the last child component. In react, data is passed top-bottom from one component to another via props. Pipe data through its props to each individual component until it responds to the last child component.

It is tedious work so "Context" comes in frame. The React Context makes it easy to access data at different levels of the component tree without passing data through props. The React Context basically works in two directions. Wrap components that share same data inside a Context provider as a parent component and entrance data inside the context via Consumer with useContext in React.

context img

Context in React is a way to pass data between nested components without passing them as "props". Simply put, data in components can be accessed through Context, no matter how deeply nested.The React Context prevent us with a problem of "prop drilling".

Why do We Need React Context?

Let's look at an exaple of life without React Context. Let's say you have some logic to get the current user in the parent component's page. There is also a Link component for accessing user information. However, the Link component is in the Para component and the Para component is in the Home component.

In order for the Link to be accessible to the user, we need to propagate it up the hierarcy as prop.

Not only is this a pain to implement, tha Home and Para components don't need the user, they just pass it down tha chain to the Link component.

Let's understand the Context with the help of an Example

Create two functional components.

Child.js

Parent.js

And import in App.js

We have created the components and nested them at the appropriate levels. In App component we have component Parent and finally component Parent we have component Child. Now let us understand how to get data from App component to Child component using Context.

There are three steps to implement when making use of context

  1. Create the Context
  2. Providing the Context with a Value
  3. Consume the Context Value

Create The Context

To create the Context we need to import createContext from React.

We can create our Context using createContext function from React. While createContext remember to export it as we'll need it outside of this file.

Providing the Context with A Value

A Provider allows all its children components to subscribe to the context's changes. The Provider must wrap the children's components for the values to be available so we wrap the component Parent. <MainContext.Provider> component Parent is going to be a child to this Provider and we need to Provide a Context value.

Provide value using <MainContext.Provider>.

Create Context object and pass value in App.js as below.

App.js

The Final step is to Consume the Context value. So from the App component let us export the Context as you saw above in App.js

Consume the Context Value

For Consuming the Context value let us import the context in the Child Component.

Use a value of Context using <MainContext.Consumer> and consume value in Child.js

In JSX, we need to make use of the Render Props Pattern to get hold of the value passed by the Context. So <MainContext.Consumer> the Context provides us with a user name and we are going to return is the user

Child.js

Output:

We can see the expected output. The value being passed from the Provider is being consumed using Render Props Pattern in the required component. The context feature itself is great as you can see but the way to consume it is slightly more difficult than we would like it to be. If we have just one Context then it will be fine but let's see how to consume multiple context values.

Back in the App component crate another Context.

And now let's Provide the Context with a value. We can Provide multiple Context values by simply adding the providers at each level. So within MainContext <SubContext.Provider> component Parent is going to be nested within <SubContext.Provider> and the value is in the string.

App.js

Now, we will import the SubContext in the Child.js to see how nested consumer works. And this is the part where it starts getting ugly. In the Child component, we have MainContext which gives us access to the user and within the function body we need to yet again use Render Props Pattern to get hold of the value.

Child.js

Output:

So the code work but it is not necessarily the most readable code just to consume two values there is just so much nesting. If only there was a better way to Consume the Context values this is where the useContext React hooks come. The useContext in React lets you Consume the Context values in a simpler way.

useContext

We've seen how to consume the Context, as in the example above. You have to approach the nesting on several levels and it's very hard to read and understand, so here we use the useContext in React hook to make it easier to read.

This hook is used to pass data from one component to another without being specified to each of the component trees. Howerver, as our application grows, we might want to share across components or even thoughout the entire application. That's when the useContext React hook comes in handy.

The useContext in React hook allows you to connect to and consume a Context. The useContext React hook takes a single argument which is the Context you want to access.

Let's take a look at a demo of useContext in React that uses Context values in a more readable and understandable format. For this, you have to import useContext from react.

Syntax:

The process of Create The Context and Providing The Context With A Value remains the same as above in Context. Only the changes come in Consume The Context Value. Simply put, the process of passing creation Context and passing values remains the same. You only need to make changes when using the values.

Three simple steps to Consume the Context values.

  1. Import useContext from react.
  2. Import the necessary Contexts.
  3. Call the useContext function passing in the Context as its argument.

Now useContext in React retuns the Context value so, let's assign the function call to a variable. We can now use these values as required. I will simply render them in the JSX. Update code in Parent.js to Consume the Context value.

Parent.js

And look how it is simple with the help of useContext hook in React.

Output

Using the useContext hook in React makes your code easier to read and easier to use.

Update the useContext

Let's start by creating a separate file for Context, i.e. "Context.js" and export it.

Context.js

And then import in the App.js file and pass the state into the value of the Provider. And take the setState opposite of the state as you see below. To share the state among every component, we have to wrap the App component in the <Context.provider>.

App.js

In the App.css file, we have created two themes one is for "dark" and the second is for "light" in which we had taken only "color" and "background-color".

App.css

Home.js

About.js

Now you can check on your "localhost" and everything works fine. This is because Context allows data to be exchanged between components. So, with the help of the useState hook, we can easily manage the Context and update the useContext in React.

FAQs

Q: What are the disadvantages of useContext hook?

A: useContext hook is very beneficial in our react applications, however it is not very useful when the size and complexity of application becomes larger.

Q: When we can use useContext?

A: When we want a variable which can be accessed anywhere in our application, then we use useContext.

Q: Which is better, useContext hook or react redux?

A: When our application is small then useContext is better, on the other hand Redux is more powerful and comes with features that useContext does not have, hence it is more suitable for bigger applications.

Q: Can useContext be used in class based components?

A: No, we cannot use useContext in class based components.

Conclusion

  • In this article, you learned about the useContext hook in React and how it works. You also learned how to update the state using the context and useContext React hook.
  • Accessing these contexts and their data is also easy with React's useContext hook.
  • React Context and useContext hooks are powerful tools for managing data.
  • Finally, the useContext hook in React is very simple. It just provides a nice interface for consuming context, but this interface is much better than the original context consumer interface.
  • The Context and useContext come to solve a few different problems that we were having in React applications- one of the most important is "prop-drilling".
  • Use useContext in React when you have deeply nested components that need to trigger these state transitions.