How to Use useContext Hook in React
This article explains how to implement the useContext
hook in React to manage global state and avoid prop drilling. You will
learn the three essential steps to set up context—creating, providing,
and consuming context—accompanied by a practical, straight-to-the-point
code example.
What is useContext?
In React, data is typically passed top-down via props. However, this
can become cumbersome for global data (like themes, user profiles, or
language preferences) that many components need. The
useContext hook solves this by allowing components to
access global state directly, bypassing intermediate components.
Step-by-Step Implementation
To implement useContext in your React application,
follow these three steps:
1. Create the Context
First, use the createContext function from React to
initialize your context. You can optionally pass a default value as an
argument.
import { createContext } from 'react';
const ThemeContext = createContext(null);2. Provide the Context
Wrap the components that need access to the data with the Context
Provider. Use the value prop to pass down the state or
functions you want to share.
import React, { useState } from 'react';
export default function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<PageLayout />
</ThemeContext.Provider>
);
}3. Consume the Context
Inside any nested child component, import the useContext
hook and your created context to access the shared values.
import React, { useContext } from 'react';
function Button() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<button
onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
style={{ background: theme === 'light' ? '#fff' : '#333' }}
>
Toggle Theme
</button>
);
}Complete Working Example
Here is how all the pieces fit together in a single file:
import React, { createContext, useContext, useState } from 'react';
// 1. Create the Context
const ThemeContext = createContext();
export default function App() {
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
setTheme((prev) => (prev === 'light' ? 'dark' : 'light'));
};
return (
// 2. Provide the Context
<ThemeContext.Provider value={{ theme, toggleTheme }}>
<div style={{
background: theme === 'light' ? '#fff' : '#222',
color: theme === 'light' ? '#000' : '#fff',
height: '100vh',
padding: '20px'
}}>
<h1>React useContext Demo</h1>
<Navbar />
</div>
</ThemeContext.Provider>
);
}
// An intermediate component that doesn't need to pass props down
function Navbar() {
return (
<nav>
<ThemeButton />
</nav>
);
}
// 3. Consume the Context
function ThemeButton() {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
<button onClick={toggleTheme}>
Switch to {theme === 'light' ? 'dark' : 'light'} mode
</button>
);
}Key Considerations
- Re-renders: Any component consuming a context will automatically re-render whenever the context value changes. To optimize performance, keep your context state as localized or split as possible.
- Fallback Values: The default value passed to
createContext(defaultValue)is only used if a component attempts to consume the context outside of a matching<Context.Provider>.