
React Context API
Prop drilling is like a game of telephone — it starts off fine, but quickly turns chaotic. As your React app grows, managing your application's state through props becomes a mess. That’s where the Context API steps in.
Used well, Context API simplifies architecture and improves maintainability of your application. Used poorly, it can wreck your application's performance. In this guide, we’ll unpack how to use React Context API the right way — with structure, intention, and minimal overhead.
What is React Context API?
React Context API is a way to manage state in a React application. It is a way to share data between components without having to pass props through multiple levels of the component tree.
Common use cases:
- Theme toggles (light/dark mode)
- Authentication state
- User preferences
- Feature flags
- Global modals or toasts
What it’s not good for:
- High-frequency updates (e.g., real-time typing)
- Local component state
- Complex state logic with side effects
Setting Up Context
You can implement the context API in your application in three steps:
- create a context
- provide that context to a part of your app,
- consume it wherever it's needed
Let's say you have a button in your navigation bar that allows users to change the theme of the website, and you want those changes to be accessible and reflected in other parts of the website.
First, add a context folder to your project. This folder will contain all the context files for your application, allowing you to easily organize your contexts.
Then, create a file called ThemeContext.js
in this folder. This file will be responsible for managing the website's theme state globally. Remember, you can give your context any name that reflects its purpose.
Here, you're creating a context called ThemeContext
using the createContext
function. This method takes an argument to set a default value for the context if no provider is available, which is light
in this case.
Next, you're creating a provider component. The provider component is responsible for providing the context to the parts of your app that need it. Here, children represents the parts of your app that need the context.
The provider component accepts a value prop that contains the data being shared. In this case, it's the theme and the toggleTheme function to switch between light and dark mode.
import { createContext, useState } from "react";
export const ThemeContext = createContext("light");
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState("light");
const toggleTheme = () => {
setTheme((prevTheme) => (prevTheme === "light" ? "dark" : "light"));
};
return <ThemeContext.Provider value={{ theme, toggleTheme }}>{children}</ThemeContext.Provider>;
};
Step 2: Provide the Context
Then, you need to wrap your application in the provider component. The App.js
file is ideal location for this because you can wrap the entire application in the provider component. Of course, you can wrap it in a specific part of your application if you want to.
import "./App.css";
import Card from "./components/Card";
import Navbar from "./components/Navbar";
import { ThemeContextProvider } from "./context/ThemeContext";
function App() {
return (
<ThemeContextProvider>
<div className="app">
<Navbar />
<Card></Card>
</div>
</ThemeContextProvider>
);
}
export default App;
Step 3: Consume the Context
Now, everything is set up. You can consume the context using the useContext
hook in any component that needs it. For example, you can consume the context in the Navbar
component so that you can access the theme and the toggleTheme function.
import React, { useContext } from "react";
import { themeContext } from "../context/ThemeContext";
const Navbar = () => {
const { theme, toggleTheme } = useContext(themeContext);
return (
<nav className={theme === "light" ? "light-nav" : "dark-nav"}>
<h1>My App</h1>
<div>
<span>Current Theme: {theme}</span>
<button onClick={toggleTheme}>Toggle Theme</button>
</div>
</nav>
);
};
export default Navbar;
Additionally, you can consume the context in the Card
component so that you can access the theme and the toggleTheme function.
import React, { useContext } from "react";
import { themeContext } from "../context/ThemeContext";
const Card = () => {
const { theme } = useContext(themeContext);
return (
<div className={theme === "light" ? "light-card" : "dark-card"}>
<h2>Themed Card</h2>
<p>
This card's style changes based on the current theme. The current theme is: <strong>{theme}</strong>.
</p>
</div>
);
};
export default Card;
Conclusion
React Context API is a powerful tool that can help you manage state in a React application. It is a way to share data between components without having to pass props through multiple levels of the component tree.