DEV Community

Cover image for How to use React Context
muhammadev
muhammadev

Posted on • Edited on

How to use React Context

Prerequisite

This article assumes you have a basic understanding of the React.js framework.

What is Context?

Context is the React solution for creating global data. This makes it consumable from any component, no matter how deep it is.

The basic example of using Context. Assume you need to use the theme state. And it's defined in the App component, from the GreatGrandChild component. To do that, you'll pass the state through each component in the components tree until you reach the GreatGrandChild component.

Context saves you that burden of prop drilling states and methods. Create a separate context file holding the state and its methods.

Creating A Context

Creating a Context has 3 steps: creating, providing, and consuming. To create a Context create a file under the src directory of the project. It'll be named after the context's name such as themeContext.js. Then use createContext API which creates the Context object. Finally, export the context object.

In src/themeContext.js file

 

Providing A Context

Each context object has a Provider component. The Provider component is used to provide the context to any of its children components. A Provider component has a value object prop which holds the context value and the updater method.

Think of the Provider component as the house of the context. The components inside that house have access to it, so they can consume it and listen to its updates. So, whenever there is a change, all the consumer components are re-rendered.

To make things easier, create the Provider component inside the context file.

In src/themeContext.js file

 

Now that we have the Provider component, let's use it for providing the context. Import the ThemeContextProvider component from inside App.js. Then, pass the children components to it.

In src/App.js

 

Consuming A Context

You have to tell React which component is dependent on the context. So that not every component is re-rendered on changes.

Note: There can be more than one provider in the components tree. The consumer components match the value of the nearest parent provider. If there are no providers above the consumer, it will receive the default value from the context file.

From class components

To consume the context object from a class-based component, assign the context object to a static contextType and you're good to go. This way you can destructure the theme value and its updater from anywhere inside a component class.

In src/components/DeepLevelComponent.jsx

 

Another way to consume a context from class-based components is to use the themeContext.Consumer component but it's more of a legacy way. The trade-off here is that you can't use the Context value anywhere but inside the render method. On contrary, contextType allows you to use the context in any lifecycle method besides the render method.

From functional components

It's not very different. We'll use React hook useContext. It does the same job as static contextType.

In src/components/ChildComponent.jsx

 

Summary

Using context is easy and helpful. It could be what you're looking for, but be careful not to miss use it.

That's it. I hope I clarified things enough. Feel free to write your thoughts in the comment section below.

Top comments (3)

Collapse
 
elianbecali profile image
Elian Becali

Very good man!

Collapse
 
sqlrob profile image
Robert Myers

When creating the provider, why the additional level of indirection on setTheme?

Collapse
 
muhammadev profile image
muhammadev

If you mean the "updateTheme" method, it's meant to be an example of a method that can do more than just updating the theme state. For example, it could be a method that triggers a fetch request, in which updating the state is not a direct step.