How to Implement Dark Mode in React.js Applications

In recent years, dark mode has become a popular feature in many applications. It not only provides a visually appealing alternative to the traditional light mode but also offers benefits such as reduced eye strain in low - light environments and lower power consumption on devices with OLED screens. React.js, a widely used JavaScript library for building user interfaces, provides several ways to implement dark mode in applications. This blog post will guide intermediate - to - advanced software engineers through the process of implementing dark mode in React.js applications, covering core concepts, typical usage scenarios, and best practices.

Table of Contents

  1. Core Concepts of Dark Mode in React.js
  2. Typical Usage Scenarios
  3. Step - by - Step Implementation
    • Using State Management
    • Leveraging CSS Variables
    • Storing User Preference
  4. Best Practices
  5. Conclusion
  6. FAQ
  7. References

Core Concepts of Dark Mode in React.js

State Management

In React, state is used to manage data that can change over time. To implement dark mode, we can use a boolean state variable to represent whether the application is in dark mode or light mode. For example, we can set isDarkMode to true for dark mode and false for light mode. When the user toggles the mode, we update this state variable, and React will re - render the components to reflect the new mode.

CSS Styling

There are two main approaches to applying dark mode styles in React: inline styles and CSS classes. Inline styles can be set dynamically based on the state variable. For instance, if isDarkMode is true, we can set the background color to a dark shade. CSS classes, on the other hand, can be toggled based on the state. We can define separate classes for dark and light modes and add or remove them from components as needed.

CSS Variables

CSS variables (custom properties) are a powerful tool for implementing dark mode. We can define a set of variables for colors, such as --background-color and --text-color, and then set different values for these variables in dark and light modes. In React, we can update these variables in the document’s root element based on the state of the dark mode.

Typical Usage Scenarios

User Preference

Many users prefer to use dark mode, especially in low - light environments like at night or in a dimly lit room. By providing a dark mode option, we can enhance the user experience and make the application more accessible.

Branding and Design

Dark mode can be used as part of the brand’s design strategy. Some brands use dark mode to create a more modern, sleek, or sophisticated look for their applications.

Power Saving

On devices with OLED screens, dark mode can significantly reduce power consumption. Since OLED pixels emit light individually, displaying black or dark colors consumes less power.

Step - by - Step Implementation

Using State Management

  1. Set up the state:
    import React, { useState } from 'react';
    
    const App = () => {
        const [isDarkMode, setIsDarkMode] = useState(false);
    
        const toggleDarkMode = () => {
            setIsDarkMode(prevMode => !prevMode);
        };
    
        return (
            <div>
                <button onClick={toggleDarkMode}>
                    {isDarkMode? 'Switch to Light Mode' : 'Switch to Dark Mode'}
                </button>
                {/* Other components */}
            </div>
        );
    };
    
    export default App;
  2. Apply styles based on the state:
    import React, { useState } from 'react';
    
    const App = () => {
        const [isDarkMode, setIsDarkMode] = useState(false);
    
        const toggleDarkMode = () => {
            setIsDarkMode(prevMode => !prevMode);
        };
    
        const appStyle = {
            backgroundColor: isDarkMode? '#121212' : '#ffffff',
            color: isDarkMode? '#ffffff' : '#000000'
        };
    
        return (
            <div style={appStyle}>
                <button onClick={toggleDarkMode}>
                    {isDarkMode? 'Switch to Light Mode' : 'Switch to Dark Mode'}
                </button>
                {/* Other components */}
            </div>
        );
    };
    
    export default App;

Leveraging CSS Variables

  1. Define CSS variables in the global CSS:
    :root {
        --background-color: #ffffff;
        --text-color: #000000;
    }
    
    .dark-mode {
        --background-color: #121212;
        --text-color: #ffffff;
    }
  2. Update the root element’s class in React:
    import React, { useState } from 'react';
    
    const App = () => {
        const [isDarkMode, setIsDarkMode] = useState(false);
    
        const toggleDarkMode = () => {
            setIsDarkMode(prevMode => !prevMode);
            const root = document.documentElement;
            if (isDarkMode) {
                root.classList.remove('dark-mode');
            } else {
                root.classList.add('dark-mode');
            }
        };
    
        return (
            <div>
                <button onClick={toggleDarkMode}>
                    {isDarkMode? 'Switch to Light Mode' : 'Switch to Dark Mode'}
                </button>
                {/* Other components */}
            </div>
        );
    };
    
    export default App;
  3. Use the CSS variables in component styles:
    body {
        background-color: var(--background-color);
        color: var(--text-color);
    }

Storing User Preference

To remember the user’s dark mode preference, we can use the browser’s localStorage.

import React, { useState, useEffect } from 'react';

const App = () => {
    const [isDarkMode, setIsDarkMode] = useState(() => {
        const storedMode = localStorage.getItem('darkMode');
        return storedMode? JSON.parse(storedMode) : false;
    });

    useEffect(() => {
        localStorage.setItem('darkMode', JSON.stringify(isDarkMode));
        const root = document.documentElement;
        if (isDarkMode) {
            root.classList.add('dark-mode');
        } else {
            root.classList.remove('dark-mode');
        }
    }, [isDarkMode]);

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

    return (
        <div>
            <button onClick={toggleDarkMode}>
                {isDarkMode? 'Switch to Light Mode' : 'Switch to Dark Mode'}
            </button>
            {/* Other components */}
        </div>
    );
};

export default App;

Best Practices

  • Accessibility: Ensure that the contrast ratio between text and background colors meets the accessibility standards in both dark and light modes. This helps users with visual impairments to read the content easily.
  • Performance: Minimize the number of re - renders when toggling the dark mode. For example, if using CSS variables, updating the root element’s class is more performant than using inline styles for every component.
  • Testing: Test the dark mode thoroughly on different devices and browsers to ensure a consistent experience.

Conclusion

Implementing dark mode in React.js applications can enhance the user experience, improve branding, and save power. By understanding the core concepts of state management, CSS styling, and CSS variables, and following the step - by - step implementation and best practices, intermediate - to - advanced software engineers can easily add this popular feature to their React applications.

FAQ

Q1: Can I use a third - party library to implement dark mode in React?

Yes, there are several third - party libraries available, such as styled - components and emotion, which can simplify the process of applying styles based on the dark mode state.

Q2: How do I handle transitions between dark and light modes?

You can use CSS transitions to create smooth transitions between dark and light modes. For example, you can add a transition property to the elements with changing colors.

body {
    transition: background - color 0.3s ease, color 0.3s ease;
}

Q3: What if the user’s device has a system - wide dark mode setting?

You can detect the system - wide dark mode setting using the prefers - color - scheme media query in CSS. In React, you can use the useMediaQuery hook from the react - responsive library to handle this.

References