useContext hook in React

Alex
5 min readFeb 3, 2021

Recently I have been converting many of class components within my project to functional components the main reasoning for this is that recently I have been using and experimenting with hooks which are a fantastic addition to both React and React-Native. So I thought it would be cool to create an article explaining the “useContext” hook as well as write some simple example code.

What is useContext?

useContext is a hook that allows us to pass data to components that are multiple levels within the component tree without having to pass in props to each level of the component tree . An example being you have Child1 & Child2 components as well as a root App.js file. You want to pass a prop called name from App.js to the Child2 component and the Child2 component is within the Child1 component that means we would have to pass the name prop through multiple components for it to get to where we wanted which can be cumbersome especially if we need to pass in multiple props multiple times. UseContext saves us the hassle of this so we can just pass the props to the components we want them to go to.

Code example walkthrough

Ok so now I will go through a very basic example of how to use the useContext hook and explain each segment of code.

We will be using React for this tutorial so in your terminal (and ensure you create this project somewhere you prefer on your system i.e. desktop, downloads, documents folder) enter the command.

create-react-app usecontextexample

This command will begin to create an empty react project.

Once this has been completed open the project in your chosen editor, I use Visual Studio Code.

Now run the below command in the terminal of your chosen editor. The keyboard shortcut to open the terminal on Visual Studio Code on a mac is “ctrl” + `

npm start

This will start the React project.

After you have done this open the App.js file and import createContext from React.

The createContext is used to create a context object that will be used in conjunction with a Provider I will expand on this in a little bit.

So your React import should look like the below

import {createContext} from 'react';

Now outside of the App function create a const variable that is equal to createContext like the below we will set it to export so we can use it in other components.

export const nameContext = createContext();

Every context object will be associated with a provider React component which allows the consuming components to “subscribe” to changes within context.

The Provider component will use a prop called value to pass down data to consuming child components of the provider. As a note, Providers can be nested to allow the overriding of values in components deeper down the component tree hierarchy, furthermore, Providers can be connected to many consumer components. In addition, all component consumers of the provider will automatically re-render when the prop value changes.

Our next task is to create 2 new components in the src folder of our React project. Name these components Child1 and Child2.

Below is the code for Child1 component.

import React from 'react';import Child2 from './Child2';function Child1(){return(<Child2/>)}export default Child1;

Below is the code for the Child2 component

import React from 'react';function Child2(){return(<div><div><h6>Name from Child2</h6></div></div>)}export default Child2;

Now replace the App function within the App.js file with the below.

function App() {return (<div className="App"><header className="App-header"><Child1/></header></div>);}

Your app should now look like the below where we are showing the Child1 component output.

So now our next step is to create a const variable called name inside of the App function (but outside of the return statement) and assign it your name.

We will now wrap the context provider around the Child1 component.

So at the moment our App function should look like the below.

function App() {const name = 'Alex';return (<div className="App"><header className="App-header"><nameContext.Provider><Child1/></nameContext.Provider></header></div>);}

In hindsight I maybe should have used capital N for NameContext, oh well.

We will now use the value prop of the Provider and set it equal to the name const variable we created.

<nameContext.Provider value={name}><Child1/></nameContext.Provider>

Once you have done that open the file Child2. We will now import the hook useContext.

import React, { useContext } from ‘react’;

The useContext hook will accept the context object we created in the App.js file as an argument and will return the current value for that context. When the closest Provider component updates the useContext hook will trigger the child components of the Provider to re-render with the most up to date value for the Provider.

The next step is to retrieve the current value of the context provider. To do this we will first import the context object into Child2 component like so.

import nameContext from './App';

The second step is to create a const variable inside of the Child2 component but outside of the return statement. So now our Child2 component should look like the below

import React, { useContext } from 'react';import {nameContext} from './App';function Child2(){const nameValue = useContext(nameContext);return(<div><div><h6>Name from Child2</h6></div></div>)}export default Child2;

So now the variable nameValue contains the current value for the Context Provider we created earlier which will be the value from the name variable we created. We can now use the nameValue within the jsx of the component like so.

return(<div><div><h6>{nameValue} from Child2</h6></div></div>)

So now our app looks like the below.

It says “Alex” because that is the value we passed in to the Context Provider in the App.js file and we are using the useContext hook to extract the current value of the context object that we pass into the “useContext” hook. We can then use this value anywhere in the component.

This way of passing data around solves the issue of having to pass down a prop through a multitude of components just to use it in the one component. However, there is a drawback to using context and especially if you are using one context to pass around multiple values, and that is the fact that once the context value changes every component associated with the context will re-render this could have potential performance issues.

--

--