✏ React Context
React Context is a convenient solution for situations when you have a big application, where lots of deeply nested components need access to the same state variable. Typical examples are the colour theme that's used everywhere in the app (dark mode/light mode), or the current language in multilingual pages.
Those would be considered "global state", and instead of drilling the props through the whole component tree, Context allows to give each component direct access to that state. You can have as many different Contexts as you like.
Since there's enough great resources out there that explain Context perfectly well, this post will only be a short summary about the basic principles and how to use it (in functional components).
✏ Creating a Context
To start, create a file colourContext.js, import createContext
from React and export the created Context:
import { createContext } from 'react';
export const ColourContext = createContext(optionalInitialValue);
Bringing that into App.js:
import { ColourContext } from './contexts/colourContext.js';
Logging that shows that it's an object with two properties: Provider and Consumer. Both are React components that do what their names suggest - the Provider wraps all parts of the app that need a certain piece of global state, and the Consumers can subscribe to get access to the provided value.
✏ Context Provider
You could use the Provider now by directly accessing the .Provider
property (note that it needs a value property):
App.js
import { ColourContext } from './contexts/colourContext.js';
function App(){
return (
<ColourContext.Provider value={ colour }>
{/* ... */}
</ColourContext.Provider>
)
}
This isn't particularly practical, because you don't want to define that value within the App component, it should rather be defined within colourContext.js. Also, it makes sense to pass a function alongside the current value, to update Context from within a child component.
To do so, the context file also exports a Provider component that contains all the logic to maintain and update the Context state:
import React, { useState, createContext } from 'react';
const colours = [
'red',
'orange',
'orangered',
'darkred',
'crimson',
'firebrick',
'tomato'
];
// import this in every child that needs access to this context
export const ColourContext = createContext();
// import wrapper component in App
function ColourContextProvider({ children }) {
const [colour, setColour] = useState('red');
const changeColour = () => {
setColour(colours[Math.floor(Math.random() * 7)]);
};
return (
// pass current value and updater function as value down to children
<ColourContext.Provider value={{ colour, changeColour }}>
{children}
</ColourContext.Provider>
);
}
export default ColourContextProvider;
The only thing that App needs from this file is the Provider component. Every child of App has now access to this Context, for example a button to change the colour:
App.js
import ColourContextProvider from './contexts/colourContext.js';
import ColourButton from './components/ColourButton.js';
function App(){ return ( ) }
✏ Context Consumer
The easiest way to subscribe to Context is by using the useContext
API. It takes a Context object as argument (the specific Context you're subscribing to), and has the current value and the update function as properties on it:
import React, { useContext } from 'react';
import { ColourContext } from '../contexts/colourContext.js';
function ColourButton() {
const colourContext = useContext(ColourContext);
// access value and update function
return (
<button
style={{ background: colourContext.colour }}
onClick={colourContext.changeColour}
>
New Colour
</button>
);
}
export default ColourButton;
Every time the value of Context changes, all subscribers will re-render with the updated value.
✏ Recap
This post covered:
- how to use React Context in functional components
✏ Thanks for reading!
I do my best to thoroughly research the things I learn, but if you find any errors or have additions, please leave a comment below, or @ me on Twitter. If you liked this post, I invite you to subscribe to my newsletter. Until next time 👋
✏ Previous Posts
You can find an overview of all previous posts with tags and tag search here: