DEV Community

Cover image for Understanding the React Context API
Abuka-Victor
Abuka-Victor

Posted on

Understanding the React Context API

The React Context API allows you to have a general data store for state management. In simple terms it acts as a bank of states that components can directly access.

Now, how might this be useful. We know that React lets you split up your application into components and some of these components are subject to conditional rendering. That is, they show different stuff based on the current state of the application. By “state”, I mean any variable piece of information that can be monitored in your application, such as whether a user is signed in or not, the number of likes on a post, etc stuff like that. Now, depending on the logical arrangement of your components, some components may need to react to state changes of other components that a very far away from them.

Component Logic Hierarchy

To explain this, I have this diagram above. Root is of course the root component and A and B are children of it. C, D and E are children of A and G,H and I are children of B. This is our imaginary setup for our company. If component C is supposed to react to a state change in component H, how do you think that can happen. Without the context API, we could create the state in the Root component and pass it down to H using props, and also pass it down to C using props. That way when we setState() in component H then a re-render fires in component C. This is called Prop Drilling and it will work for what we have currently but imagine you have thousands of components just like C and H, just thinking about how messy it will be to do it this way gives me goosebumps.

So what is the native solution?, you guessed it, The React Context API. I said native because tools like Redux and Mobx do the same thing only that you have to install them first. But They help you manage state better by providing sort of a central data store that all components have access to. So how exactly does it work and how do you set it up. Trust me this is the easy part.

When I work, I like to put my contexts in a context folder just like you keep components or screens in different folders. So first of all create a new folder called “contexts”. You can create different data stores for different things. One to store user details from authentication, another to store maybe a users cart or you can really just make one huge data store for everything, that’s entirely up to you. In this folder, create a file called “user.context.js”, this is just an example, you can name it whatever you want but I want to create a context that stores user data so it makes sense for me to name it like so. In this folder let's have the code below.

import {createContext, useState} from 'react';

export const userContext = createContext({
currentUser: null,
setCurrentUser: () => null,
});
Enter fullscreen mode Exit fullscreen mode

The code above only imports the createContext function that we can use to initialise a data store, we will make use of useState later. Just like useState, we initialise it with some default or starting values which is null. Next We add these.

export const UserProvider = ({ children }) => {

const [currentUser, setCurrentUser] = useState(null);
const value = {currentUser, setCurrentUser};

return <userContext.Provider value={value}>{children}</userContext.Provider>;
}
Enter fullscreen mode Exit fullscreen mode

This creates a component that be wrapped around the root component. Any child of this component will be able to access the data we have initialised. As you must have guessed, react context leverages on useState to function. The last step is to wrap this provider round our app component in index.js. This is only the setup.

import { UserProvider } from './contexts/user.context'

...

root.render(

<UserProvider>
  <App />
</UserProvider>

)
Enter fullscreen mode Exit fullscreen mode

To use the data we have in store in our component we use the useContext hook like so.

import { useContext } from 'react';
import { userContext } from './../contexts/user.context';

export default SomeComponent = () => {

const { currentUser } = useContext(userContext);

...
}
Enter fullscreen mode Exit fullscreen mode

Ah yes, we can decide to only collect what we need from the context. In some components we may need the setCurrentUser function in some others we may need both.

There you have it folks. React Context in simple terms. If you enjoyed reading this article and you want to understand more stuff like these please let me know in the comment section, including what you would love to learn next. If you spot any errors, please I would love to know as well.

Top comments (0)