JAVASCRIPT
Global Theme Toggling with useContext
Easily implement a global theme toggling feature in React using `useContext` and `useState` hooks, avoiding prop drilling for application-wide styles.
import React, { createContext, useContext, useState } from 'react';
// 1. Create a Context
const ThemeContext = createContext(null);
// 2. Create a Provider Component
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light'));
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
// 3. Create a Custom Hook for Consumers
function useTheme() {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
}
// Example Usage in Components
function ThemeButton() {
const { theme, toggleTheme } = useTheme();
return (
<button onClick={toggleTheme}>
Switch to {theme === 'light' ? 'Dark' : 'Light'} Theme
</button>
);
}
function DisplayTheme() {
const { theme } = useTheme();
return <p>Current Theme: {theme}</p>;
}
// App component to demonstrate
function App() {
const [appTheme, setAppTheme] = useState('light'); // Internal state for dynamic styling demonstration
// A helper function to update local state based on context theme.
// In a real app, you might apply classes or use CSS variables directly.
const updateAppTheme = (newTheme) => {
setAppTheme(newTheme);
};
return (
<ThemeProvider>
<ThemeContext.Consumer>
{({ theme }) => (
<div style={{ padding: '20px', background: theme === 'light' ? '#fff' : '#333', color: theme === 'light' ? '#333' : '#fff' }}>
<h1>My Themed App</h1>
<DisplayTheme />
<ThemeButton />
</div>
)}
</ThemeContext.Consumer>
</ThemeProvider>
);
}
export default App;
How it works: This snippet demonstrates how to use `useContext` to manage global state, specifically a theme preference, without 'prop drilling'. A `ThemeContext` is created, and a `ThemeProvider` component uses `useState` to manage the theme. This provider wraps the components that need access to the theme. Consumer components then use the `useContext` hook (often wrapped in a custom hook like `useTheme`) to access the current theme and the function to toggle it, allowing for consistent theme management across the application.