What is Context?
Think of React Context like a walkie-talkie system for your components. Instead of passing notes through a chain of people (prop drilling), you just broadcast on a channel and anyone tuned in gets the message.
Context lets you share data across your component tree without manually passing props at every level. It's React's built-in solution to the prop drilling problem we talked about earlier.
But here's the thing โ context isn't a free lunch. It's powerful, but you need to know when and where to use it wisely.
Creating Context
Creating a context is dead simple. You call createContext and you get a context object. That's it. The real magic happens with the Provider.
const ThemeContext = createContext("light");
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
The Provider wraps the part of your tree that needs access to the shared value. Any component inside that Provider can grab the value โ no matter how deeply nested it is.
You can also pass a default value to createContext, which gets used if a component tries to use context without a Provider above it.
Try it Yourself โProvider and Consumer
There are two ways to consume context: the useContext hook (modern and clean) or the Context.Consumer component (older but still valid).
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button className={theme}>
Click me
</button>
);
}
The useContext hook is the way to go. It's cleaner, easier to read, and works inside any functional component. Just make sure the component using useContext is wrapped by the corresponding Provider higher up in the tree.
You can have multiple providers for different contexts. Theme in one, user data in another, language preferences in a third. They don't interfere with each other.
Try it Yourself โWhen Should You Use Context?
Context is great for truly global data โ things like the current theme, authenticated user, selected language, or any value that many components across your app need access to.
Don't use context for every little thing though. If only two or three components need a value and they're close in the tree, plain props are simpler and more explicit.
A good rule of thumb: if you find yourself passing the same props through three or more levels, that's a sign context might be the right tool. For complex state with frequent updates, consider pairing context with useReducer or a state management library.