Pull to refresh

React Custom Hook: useDarkMode

Level of difficulty Medium
Reading time 4 min
Views 2K

In this article series, we embark on a journey through the realm of custom React hooks, discovering their immense potential for elevating your development projects. Our focus today is on the "useDarkMode" hook, one of the many carefully crafted hooks available in the collection of React custom hooks.

Github: https://github.com/sergeyleschev/react-custom-hooks

import { useEffect } from "react"
import useMediaQuery from "../useMediaQuery/useMediaQuery"
import { useLocalStorage } from "../useStorage/useStorage"

export default function useDarkMode() {
    const [darkMode, setDarkMode] = useLocalStorage("useDarkMode")
    const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)")
    const enabled = darkMode ?? prefersDarkMode

    useEffect(() => {
        document.body.classList.toggle("dark-mode", enabled)
    }, [enabled])

    return [enabled, setDarkMode]

This custom hook combines two other handy hooks useMediaQuery and useStorage, to provide a seamless dark mode experience. It automatically detects the user's preferred color scheme and persists the dark mode state in the browser's local storage.

One of the main advantages of "useDarkMode" is its simplicity. With just a few lines of code, you can enable dark mode in your React application. By invoking this hook, you'll receive the current dark mode state and a function to toggle it.

The "useDarkMode" hook dynamically updates the HTML body class to apply the "dark-mode" styling whenever dark mode is enabled. This approach ensures consistency across all components without the need for manual class manipulation.

body.dark-mode {
    background-color: #333;

You can use the "useDarkMode" hook in various scenarios. Whether you're building a blog, e-commerce platform, or a content-heavy application, dark mode can enhance the user experience, reduce eye strain, and conserve device battery life. The possibilities are endless, and this custom hook makes it a breeze to implement.

To make it even easier, I've included a simple example component, "DarkModeComponent," that showcases how to use the "useDarkMode" hook. By clicking the "Toggle Dark Mode" button, you can instantly switch between light and dark themes. The button's appearance changes dynamically, reflecting the current mode.

import useDarkMode from "./useDarkMode"
import "./body.css"

export default function DarkModeComponent() {
    const [darkMode, setDarkMode] = useDarkMode()
    return (
            onClick={() => setDarkMode(prevDarkMode => !prevDarkMode)}
                border: `1px solid ${darkMode ? "white" : "black"}`,
                background: "none",
                color: darkMode ? "white" : "black",
            Toggle Dark Mode

Note that browsers have native support for dark mode. To opt in:

<meta name="color-scheme" content="light dark">

Most browsers will trigger a light-on-dark color scheme just by doing this. In CSS you can use media queries:

@media (prefers-color-scheme: dark) {
    .some-component {
        color: white;
        background-color: #1c1c1c;

This way your site will automatically adapt to the dark mode setting of the browser or OS.

This approach leverages the browser's built-in functionality, and your suggestion provides an excellent alternative for implementing dark mode without relying solely on custom React hooks. But..

Benefits of "useDarkMode" Custom Hook:

  1. Full Control and Customization: With the "useDarkMode" custom hook, you have complete control over the design, color palette, and styling of your dark mode. You can tailor the appearance to match your brand and design intent.

  2. Simplified CSS: The custom hook abstracts the complexity of toggling between light and dark mode styles, reducing the complexity of your CSS codebase.

  3. User-Initiated Toggle: The hook allows users to switch between light and dark modes within your website, independent of their system-wide settings. This can improve user engagement and experience.

  4. Integration with UI Components: You can easily integrate the "useDarkMode" hook into your UI components, allowing for a seamless and unified dark mode experience throughout your application.

Drawbacks of Browser's Built-in Dark Mode:

  1. Limited Customization: Relying solely on browser dark mode settings limits your ability to customize the design and appearance of your dark mode to align with your branding and user experience goals.

  2. Dependency on User Settings: Your website's appearance depends on the user's system-wide dark mode setting. This might not align with your design intent and could lead to a disconnect between your brand and the user experience.

  3. Compatibility Issues: Not all browsers or platforms support the prefers-color-scheme media query, leading to potential compatibility issues and inconsistent behavior.

  4. Limited Accessibility Control: Browser-based dark mode might not provide the accessibility features needed for all users, potentially excluding those with specific visual needs.

"useDarkMode" custom hook offers greater control, customization, consistency, and accessibility over relying solely on the browser's built-in dark mode variant. It empowers you to create a tailored dark mode experience that aligns with your design goals while overcoming the limitations and potential drawbacks associated with browser-native dark mode.

Full Version | React Custom Hooks: https://habr.com/en/articles/746760/

Total votes 6: ↑4 and ↓2 +2
Comments 0
Comments Leave a comment