JAVASCRIPT
Implementing a Simple Dark/Light Theme Switch with useContext
Create a global theme context in React using useContext to easily manage and switch between dark and light modes across your application without prop drilling.
import React, { createContext, useContext, useState } from 'react';
// 1. Create a Context
const ThemeContext = createContext(null);
// 2. Create a Provider Component
export function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light'); // 'light' or 'dark'
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 (optional but recommended)
export function useTheme() {
const context = useContext(ThemeContext);
if (context === undefined) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
}
// Example Component consuming the theme
function ThemeSwitcher() {
const { theme, toggleTheme } = useTheme();
const appStyles = theme === 'dark' ?
'bg-gray-800 text-gray-100 p-8 min-h-screen transition-colors duration-300'
: 'bg-white text-gray-900 p-8 min-h-screen transition-colors duration-300';
return (
<div className={appStyles}>
<h1 className="text-3xl font-bold mb-4">Current Theme: {theme}</h1>
<button
onClick={toggleTheme}
className="px-5 py-2 bg-indigo-600 text-white font-semibold rounded-md shadow-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
>
Toggle Theme
</button>
<p className="mt-4">This content adapts to the theme.</p>
</div>
);
}
export default ThemeSwitcher;
How it works: This snippet demonstrates how to implement a global theme switch using `useContext` in React. First, `createContext` establishes `ThemeContext`. A `ThemeProvider` component then wraps `children` and manages the `theme` state, exposing both the `theme` value and a `toggleTheme` function via the `value` prop of `ThemeContext.Provider`. Finally, a custom `useTheme` hook is created using `useContext` to provide an easy and safe way for any descendant component (like `ThemeSwitcher`) to access the current theme and the function to change it, effectively avoiding prop drilling for global states.