JAVASCRIPT

Implement Dark Mode with useDarkMode Hook

A custom React hook to effortlessly add dark mode functionality to your application, persisting user preference across sessions using localStorage and system preferences.

import { useState, useEffect } from 'react';

const prefersDarkMode = () =>
  window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;

const useDarkMode = () => {
  const [isDarkMode, setIsDarkMode] = useState(() => {
    try {
      const storedValue = localStorage.getItem('darkMode');
      return storedValue ? JSON.parse(storedValue) : prefersDarkMode();
    } catch (error) {
      console.error("Error reading from localStorage:", error);
      return prefersDarkMode(); 
    }
  });

  useEffect(() => {
    try {
      localStorage.setItem('darkMode', JSON.stringify(isDarkMode));
    } catch (error) {
      console.error("Error writing to localStorage:", error);
    }

    if (isDarkMode) {
      document.body.classList.add('dark-mode');
      document.body.classList.remove('light-mode');
    } else {
      document.body.classList.add('light-mode');
      document.body.classList.remove('dark-mode');
    }
  }, [isDarkMode]);

  return [isDarkMode, setIsDarkMode];
};

export default useDarkMode;

/*
// Example CSS (in a global stylesheet or component-scoped styles):
// body.light-mode { background-color: #fff; color: #333; }
// body.dark-mode { background-color: #333; color: #fff; }

// Example Usage:
function ThemeSwitcher() {
  const [isDarkMode, setIsDarkMode] = useDarkMode();

  const toggleMode = () => {
    setIsDarkMode(prevMode => !prevMode);
  };

  return (
    <div>
      <p>Current theme: {isDarkMode ? 'Dark' : 'Light'}</p>
      <button onClick={toggleMode}>
        Toggle to {isDarkMode ? 'Light Mode' : 'Dark Mode'}
      </button>
      <p>This paragraph will change color based on the theme.</p>
    </div>
  );
}
*/
How it works: The `useDarkMode` hook provides an elegant solution for implementing dark mode functionality in React applications. It manages the `isDarkMode` state, which is initialized based on user preference stored in `localStorage` or the system's `prefers-color-scheme` setting. An `useEffect` hook ensures that `localStorage` is updated whenever `isDarkMode` changes, and critically, it applies or removes `dark-mode` (or `light-mode`) classes to the `document.body`, allowing CSS to dynamically adjust the theme. The hook returns the current mode and a setter function, similar to `useState`, for easy toggling.

Need help integrating this into your project?

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

Hire DigitalCodeLabs