Using Context in React
Ever came across a prop that might be required by components anywhere and everywhere in the hierarchy tree? Ever faced the frustration and complexity of passing a particular prop from the grandparent to the parent and then all the way down to the child (commonly known as prop drilling)? Here is where the Context API comes to one’s rescue.
From the React documentation:
Context is designed to share data that can be considered “global” for a tree of React components
Hence, React Context API is a way to essentially create global variables that can be passed around in a React app. This can be used for passing around the theme, user or current locale, etc. The following diagram shows the simplicity of usage of the context API:
Prerequisites
- Knowledge of Reactjs functional and class components
- React hooks for functional components
Let us discuss the implementation of context with the help of an example. Suppose we have to manage user for our app for which we decide to use the context API.
Creating Context
First of all, let’s create a context and name it UserContext. Then we shall also create a provider (the component that provides the value) and a consumer (the component that consumes the value) for the same.
Let’s create a file UserContext.js
import React from 'react';const UserContext = React.createContext({}); // here we can initialise with any value we want.export const UserProvider = UserContext.Provider;
export const UserConsumer = UserContext.Consumer;
export default UserContext;
Providing Context
The provider has to wrap the parent element. So let us wrap our App
component in the provider.
import React from 'react';
import { UserProvider } from './UserContext'const App = props => {
const user = { name: 'Ustat', age: 24 };
return (
<UserProvider value={user}>
<div> This is App Component </div>
</UserProvider>
)
}export default App;
In the coming sections, we will learn how to retrieve the value from the context.
Consuming Context
Providing context for both class and functional components is the same. However, consuming the context is slightly different in both cases.
- For Class Components
import React from 'react';
import { UserConsumer } from './UserContext';
class OrderInfo extends React.Component {
static contextType = UserContext;
componentDidMount() {
let user = this.context;
console.log(user); // { name: 'Ustat', age: 24 }
}
render() {
// use this if you are retrieving value using contextType.
let user = this.context;
return (
<div>{user.name}</div>
)
OR
// use this if you wish to use UserConsumer
return (
<UserConsumer>
{context => {
return <div>{context.name}</div>
}}
</UserConsumer>
)
}
}
- For Functional Components (using useContext hook)
import React, { useContext } from 'react';
import UserContext from './UserContext';
const HomePage = () => {
const user = useContext(UserContext);
console.log(user); // { name: 'Ustat', age: 24 }
return null;
}