JAVASCRIPT
Global Theme Toggle with React useContext
Implement a global dark/light theme toggle in React using the useContext hook, avoiding prop drilling and providing a simple way to manage application-wide state.
import React, { createContext, useState, useContext } from 'react';
// 1. Create a Context
const ThemeContext = createContext(null);
// 2. Create a Provider Component
export function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
setTheme(prevTheme => (prevTheme === 'light' ? 'dark' : 'light'));
};
const value = { theme, toggleTheme };
return (
<ThemeContext.Provider value={value}>
{children}
</ThemeContext.Provider>
);
}
// 3. Create a Custom Hook to Consume the Context
export function useTheme() {
const context = useContext(ThemeContext);
if (context === null) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
}
// Example Component using the theme
function ThemedButton() {
const { theme, toggleTheme } = useTheme();
const buttonStyle = {
background: theme === 'light' ? '#fff' : '#333',
color: theme === 'light' ? '#333' : '#fff',
border: '1px solid #ccc',
padding: '10px 20px',
borderRadius: '5px',
cursor: 'pointer',
};
return (
<button style={buttonStyle} onClick={toggleTheme}>
Switch to {theme === 'light' ? 'Dark' : 'Light'} Mode
</button>
);
}
// Example App Structure
function App() {
return (
<ThemeProvider>
<div style={{ padding: '20px', minHeight: '100vh', background: useTheme().theme === 'light' ? '#f0f0f0' : '#222', color: useTheme().theme === 'light' ? '#333' : '#f0f0f0' }}>
<h1>My Themed App</h1>
<ThemedButton />
<p>This paragraph also respects the theme!</p>
</div>
</ThemeProvider>
);
}
export default App;
How it works: This snippet demonstrates how to implement a global theme toggling mechanism using `useContext`. First, a `ThemeContext` is created. Then, a `ThemeProvider` component is defined, holding the theme state and a `toggleTheme` function using `useState`. This provider wraps `children` components, making the theme and toggle function available to any descendant. Finally, a custom hook `useTheme` simplifies consuming the context, allowing any component to access the current theme and the function to change it without prop drilling, showcasing efficient global state management.