JAVASCRIPT
Implement Global Theming with React's useContext
Learn how to manage application-wide themes (e.g., light/dark mode) using React's powerful useContext hook, providing a simple and efficient global state solution.
import React, { createContext, useContext, useState } from 'react';
// 1. Create a Context
const ThemeContext = createContext(null);
// 2. Create a Provider Component
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light'); // 'light' or 'dark'
const toggleTheme = () => {
setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light'));
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
// 3. Create a Custom Hook to Consume the Context
export const useTheme = () => {
const context = useContext(ThemeContext);
if (context === null) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
};
// Example Usage:
const ThemeToggle = () => {
const { theme, toggleTheme } = useTheme();
return (
<button onClick={toggleTheme}>
Switch to {theme === 'light' ? 'Dark' : 'Light'} Mode
</button>
);
};
const ThemedComponent = () => {
const { theme } = useTheme();
return (
<div style={{
background: theme === 'light' ? '#fff' : '#333',
color: theme === 'light' ? '#333' : '#fff',
padding: '20px',
borderRadius: '8px'
}}>
<h1>Hello, {theme} Theme!</h1>
<p>This component adapts to the current theme.</p>
<ThemeToggle />
</div>
);
};
const App = () => (
<ThemeProvider>
<ThemedComponent />
</ThemeProvider>
);
How it works: This snippet demonstrates how to set up a global theme management system using `useContext`. First, `createContext` defines a new context. Then, a `ThemeProvider` component uses `useState` to manage the theme state and provides it, along with a `toggleTheme` function, to all its children via `ThemeContext.Provider`. Finally, a custom hook `useTheme` is created to easily consume the theme context, making the theme and toggle function available to any component nested within the `ThemeProvider`.