The useContext
hook in React is a powerful way to share state between components without manually passing props through every level of the component tree. It makes your code cleaner, more maintainable, and is a key part of building scalable React applications.
In this article, we will explore:
- What
useContext
is - How it works under the hood
- Realistic code examples
- Best practices and pitfalls
- A visual diagram to understand its flow
1. What is useContext
?
In React, data is typically passed from parent to child via props. But when your app grows, passing props through multiple levels (also known as prop drilling) becomes cumbersome.
useContext
allows you to:
- Create a Context (a shared data store)
- Provide that context to a part of your component tree
- Access that data directly from any nested component without manually passing props
Think of it as a global state for a section of your component tree.
2. How useContext
Works
- Create a Context using
React.createContext()
. - Wrap your components with a Provider that supplies the data.
- Consume the context in any child component using
useContext
.
Here’s a simple example:
import React, { createContext, useContext, useState } from 'react';
// 1. Create Context
const ThemeContext = createContext();
function App() {
const [theme, setTheme] = useState('light');
return (
// 2. Provide Context
<ThemeContext.Provider value={{ theme, setTheme }}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
// 3. Consume Context
const { theme, setTheme } = useContext(ThemeContext);
return (
<button
style={{ background: theme === 'light' ? '#fff' : '#333', color: theme === 'light' ? '#000' : '#fff' }}
onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
>
Current Theme: {theme}
</button>
);
}
What happens here?
The App component provides a theme value to all nested components.
ThemedButton
can access theme
and setTheme
directly, without prop drilling.
3. Interactive Example
Imagine you have multiple buttons across different components that need to know the current theme. Without context, you would pass the theme through every component, even if they don’t use it.
With useContext
:
- The state is centralized.
- Any component in the tree can read and update the theme instantly.
4. Best Practices
- Use Context for Global State that Changes Infrequently
- Themes, authenticated user info, language settings
- Avoid Overusing Context
- For high-frequency updates (like mouse positions), context can trigger unnecessary re-renders
- Combine with
useReducer
for Complex State - Create a Context + Reducer for global state management like Redux-lite
5. Visual Diagram of useContext Flow
Below is a visual representation of how useContext works:
- Context Provider wraps the components.
- Context Consumers (via useContext) read the data directly.
- Updates in the provider immediately propagate to all consumers.
[ Context Provider ]
|
| provides value
v
+-------------------+
| Child Component |
| useContext() |
+-------------------+
|
| accesses context
v
No Prop Drilling!
With useContext
, your React applications become cleaner, more maintainable, and easier to scale. Combine it with hooks like useReducer
for a lightweight global state management solution.
Top comments (0)