← Back to all snippets
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.

Need help integrating this into your project?

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

Hire DigitalCodeLabs