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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs