React - Theme Toggle (Dark Mode)

Overview

Estimated time: 10–20 minutes

Implement a dark mode toggle using CSS variables and persist preference.

Try it: Theme toggle

View source
function useTheme(){
  const [theme, setTheme] = React.useState(() => localStorage.getItem('theme') || 'light');
  React.useEffect(() => {
    localStorage.setItem('theme', theme);
    const r = document.documentElement;
    const dark = theme==='dark';
    r.style.setProperty('--bg', dark? '#111':'#fff');
    r.style.setProperty('--fg', dark? '#f5f5f5':'#111');
    r.style.setProperty('--border', dark? '#333':'#ddd');
  }, [theme]);
  return [theme, setTheme];
}
function App(){
  const [theme, setTheme] = useTheme();
  return (
    <div>
      <button onClick={() => setTheme(t => t==='light'? 'dark':'light')}>Switch to {theme==='light'? 'dark':'light'} mode</button>
      <p>The page updates CSS variables to reflect the theme.</p>
    </div>
  );
}
ReactDOM.createRoot(document.getElementById('try-theme')).render(<App />);

Syntax primer

  • Use CSS variables to theme colors globally.
  • Persist the theme in localStorage to preserve user preference.

Common pitfalls

  • Forgetting to set meta color-scheme for form controls consistency.

Exercises

  1. Detect system preference via prefers-color-scheme on first load.