What is React Context?
React Context is a way to manage state globally without passing props manually at every level, a process known as "prop drilling". It is useful for sharing data like themes, authentication status, or user preferences across multiple components.
How does Context work?
Context provides a central store where values are kept and can be accessed by multiple components, which avoids deep prop drilling.
Creating and using Context
Let's break it down step by step with an example.
1. Create a Context
First, create a context using createContext().
import { createContext } from 'react';
// Create a Context for the theme (light or dark mode)
const ThemeContext = createContext('light');
export default ThemeContext;
2. Provide Context in a component
The Provider component wraps the parts of the app that need access to the context.
import ThemeContext from './ThemeContext';
function App() {
return (
<ThemeContext.Provider value="dark">
<ChildComponent />
</ThemeContext.Provider>
);
}
3. Consume Context with useContext()
Instead of passing props, use useContext() to read the context value inside a child component.
import { useContext } from 'react';
import ThemeContext from './ThemeContext';
function ChildComponent() {
const theme = useContext(ThemeContext);
return (
<div
style={{
background: theme === 'dark' ? '#333' : '#fff',
color: theme === 'dark' ? '#fff' : '#000',
}}
>
Theme: {theme}
</div>
);
}
When should you use Context?
- When multiple components need the same data, such as a theme, authentication, or user settings.
- When prop drilling becomes too complex.
- When state needs to be shared across different parts of the app.
When not to use Context?
- For values that update frequently, like animations or real-time data. Use a state management library such as Redux or Zustand instead.
- If the state is used in only a few components. Props may be simpler.
A fuller example: managing user authentication
Here is a more complete example that uses Context to manage authentication.
1. Create the Auth Context
import { createContext, useState } from 'react';
const AuthContext = createContext();
export function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const login = (username) => setUser({ name: username });
const logout = () => setUser(null);
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
}
export default AuthContext;
2. Wrap the app with AuthProvider
import { AuthProvider } from './AuthContext';
import Dashboard from './Dashboard';
function App() {
return (
<AuthProvider>
<Dashboard />
</AuthProvider>
);
}
3. Use the Auth Context in a component
import { useContext } from 'react';
import AuthContext from './AuthContext';
function Dashboard() {
const { user, login, logout } = useContext(AuthContext);
return (
<div>
{user ? (
<>
<p>Welcome, {user.name}!</p>
<button onClick={logout}>Logout</button>
</>
) : (
<button onClick={() => login('John Doe')}>Login</button>
)}
</div>
);
}
Summary
- Context is a global state tool for React.
- useContext() reads a Context value in one line.
- Provider shares data with the components below it.
- Use Context to avoid unnecessary prop drilling.
- Context can carry complex state, such as user authentication.