Why You Should Be Using React Context
Learn how to use the React Context API with the useContext Hook.

A software engineer turned developer relations engineer in the web3 space, from Australia 🇦🇺.
Search for a command to run...
Learn how to use the React Context API with the useContext Hook.

A software engineer turned developer relations engineer in the web3 space, from Australia 🇦🇺.
This is fantastic content Jarrod Watts!!! Thank you for writing about this!!
“What does dev rel do?” I see this question get asked surprisingly often. Recently, I was given the opportunity to build a developer relations program from scratch and reflect on my 3 years of experience in this role to create a strategy. I decided t...
Ever wanted to store a piece of information on-chain but keep it a secret until later? In this quick post, we'll explore the commit-reveal scheme and provide an example of how you can implement it within a smart contract using Solidity. What is the C...

In this tutorial, I'll walk you through the process of setting up Coinbase Smart Wallet inside a front-end application. By the end of the tutorial, we'll build a simple Next.js application where users can: Connect to your application via Coinbase Sm...

As part of Ethereum's rollup-centric roadmap, rollups are taking away the heavy lifting from Ethereum and scaling its throughput by orders of magnitude, reflected in the $20B+ TVL stored in L2 chains today. But, with great power, comes great respons...

This guide will show you how to build your own indexer for an EVM-compatible blockchain such as Ethereum, Polygon Proof of Stake, and more! By the end, you'll have a Docker container running Kafka that captures all blockchain events that you specify,...

As I started to get more comfortable with developing React applications, I stumbled across a frustrating problem in the applications I was building.
I wanted to be able to access information about the current signed-in user on multiple different pages and components.
To do that, I could either:
prop to all the components that needed to use it, (and some parent props that didn't!)I thought to myself, there must be a better way to do this, and I was right; enter the React Context API!
For those who prefer to consume their content via video, I have also created a YouTube Guide to follow along with this blog :-) - Let me know if you come from Hashnode!
Context provides a way to share values between components, without having to explicitly pass a prop through every level of the tree. This avoids a problem known as prop drilling.
React Context is designed to share data that is considered "global"; like the current user, a UI theme, or local preferences; such as if the user selects dark mode or light mode.
Essentially, React Contexts allow you to store some value within a parent component, and every child inside that parent can access the value.
Let's look at an example of what life is like without React Context.
Let's say we have some logic to get the current user in our parent component, Page.
We also have a Link component that I'd like to access the user information in.
BUT the Link component lives within the NavBar component, and the NavBar component lives within the PageLayout component.
So our structure looks something like this:
-> Page
-> PageLayout
-> NavigationBar
-> Link
In order for the Link to access the user, we will have to pass it down the hierarchy as props, like so:
<Page user={user}>
<PageLayout user={user}>
<NavigationBar user={user} >
<Link href={user.permalink}/>
</NavigationBar>
</PageLayout >
</Page>
This is not only annoying to implement but the PageLayout and NavigationBar components may not even need the user; they only need it to pass it down the chain to the Link component.
Let's see how a React Context could help.
The basic syntax of a React Context is:
// Create the context
const AuthContext = createContext({}); // {} here is the default value.
// A function that you would pass children components into.
// This function would return all the children passed into it, plus a context wrapped around it.
function AuthContextProvider({ children }) {
return (
<AuthContext.Provider value={/* Some value here*/}>
{children}
</AuthContext.Provider>;
}
value can be any value of your choosing.
You can pass multiple values at once by passing in an object too :-)
Previously, (before React Hooks), you would have to use a Context.Consumer to read the value stored in the Context.Provider, which looked like this:
<AuthContext.Consumer>
{value => /* render something based on the context value */}
</AuthContext.Consumer>
But, since we live in the future™, we can use the more simple useContext Hook
The useContext hook accepts the context object itself as an argument and returns the current context value, which is the current value of the value prop of the context.
The code to initialize that hook looks like this:
const useUser = () => useContext(AuthContext)
In the real world, you would likely export this hook, and in any functional component that you want to get the value of the context, you can simply import it and use it, like so:
import useUser from '../context/userContext'
and then:
// myUser contains the value of the current value in the context.
const myUser = useUser()
No need for the Consumer anymore!
Whenever the Context Provider value updates, the useContext hook triggers a re-render with the latest context value that it has to all the subscribers of the context.
A component calling
useContextwill always re-render when the context value changes.
The example context I have hinted at in the above code snippets is to have the current signed-in user available within the context.
Let's explore how we can achieve that, with an example userContext using AWS Amplify.
AuthContext.tsx:
import React, { ReactElement, useState, useEffect } from 'react';
import { createContext, useContext } from 'react';
import { Auth, Hub } from 'aws-amplify';
// initialize the context with an empty object
const UserContext = createContext({});
export default function AuthContext({ children }) {
// Store the user in a state variable
const [user, setUser] = useState(null);
useEffect(() => {
checkUser();
}, []);
// (Only once) - when the component mounts, create a listener for any auth events.
useEffect(() => {
Hub.listen('auth', () => {
// Hub listens for auth events that happen.
// i.e. Sign in, sign out, sign up, etc.
// Whenever an event gets detected, run the checkUser function
checkUser();
});
}, []);
async function checkUser() {
try {
// Get the current authenticated user
const user = await Auth.currentAuthenticatedUser();
if (user) {
// set the user in state
setUser(user);
}
}
// Error occurs if there is no user signed in.
catch (error) {
// set the user to null if there is no user.
setUser(null);
}
}
return (
<UserContext.Provider
value={{
user, // the value of the current user
setUser, // the setState method - allows us to set the current user in state from anywhere in our application
}}
>
{children}
</UserContext.Provider>
);
}
// export the hook so we can use it in other components.
export const useUser = () => useContext(UserContext);
In my _app.js file, (which in Next.JS, wraps all pages of the application):
import React, { useEffect } from 'react';
import AuthContext from '../context/AuthContext';
function MyApp({ Component, pageProps }) {
return (
<AuthContext>
<Component {...pageProps} />
</AuthContext>
);
}
export default MyApp;
Now, I can access the current signed-in user from any page in my application, with:
// De-structure user out of the value prop returned by useUser hook.
const { user } = useUser();
React Context and the useContext hook is a powerful tool to manage a piece of data that:
A helpful use case of React Context is to provide the current user to all the components of the application. I hope this helps you to understand what the React Context API is and how to use it in the modern age with hooks.
Thanks for reading :-)!
YouTube: youtube.com/channel/UCJae_agpt9S3qwWNED0KHcQ
Twitter: twitter.com/JarrodWattsDev
GitHub: github.com/jarrodwatts
LinkedIn: linkedin.com/in/jarrodwatts
Website: jarrodwatts.com