Blog>
Snippets

Shared State Management with React Context

Create a React context to share state between disparate components in Next.js 14 without prop drilling, showing a theme toggle as an example.
import { createContext, useContext, useState } from 'react';

// Define a context for the theme
const ThemeContext = createContext();
Create a React context called ThemeContext to hold the theme state.
export function ThemeProvider({ children }) {
  // State to hold the current theme
  const [theme, setTheme] = useState('light');

  // Function to toggle the theme
  const toggleTheme = () => {
    setTheme(theme === 'light' ? 'dark' : 'light');
  };

  // The context provider component
  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}
Define a ThemeProvider component that uses the ThemeContext to provide the theme and toggleTheme function to its children.
export const useTheme = () => useContext(ThemeContext);
Create a custom hook 'useTheme' for easier access to the ThemeContext.
import { useTheme } from './ThemeProvider'; // Assuming ThemeProvider is in the same file

function ThemeToggleButton() {
  const { theme, toggleTheme } = useTheme();

  return (
    <button onClick={toggleTheme}>
      {theme === 'light' ? 'Switch to Dark' : 'Switch to Light'}
    </button>
  );
}
Create a ThemeToggleButton component that uses the useTheme hook to switch themes when clicked.
import { ThemeProvider } from './ThemeProvider'; // Assuming ThemeProvider is in the same file

function App() {
  return (
    <ThemeProvider>
      {/* other components that may need access to the theme */}
      <ThemeToggleButton />
    </ThemeProvider>
  );
}
Set up the main App component to wrap parts of the app with the ThemeProvider to give access to the theme context to components like ThemeToggleButton.