Implementing Dark Mode in React: A Step-by-Step Guide
As developers, we are always on the lookout for ways to enhance user experience, and one increasingly popular feature is dark mode. Many users prefer dark mode not only for aesthetics but also for reducing eye strain and conserving battery life on OLED screens. In this article, we will explore how to easily implement dark mode in a React application.
What is Dark Mode?
Dark mode, also known as night mode, is a color scheme that uses a dark background with lighter text. This mode can help reduce blue light exposure and make reading content easier in low-light environments. It’s available across various platforms and applications, from operating systems to individual applications like web apps and mobile apps.
Benefits of Dark Mode
- Less Eye Strain: Many users find dark backgrounds easier to look at, especially in dim lighting.
- Battery Efficiency: On OLED screens, dark pixels consume less power.
- Aesthetic Appeal: Dark mode has become a design trend that many users appreciate.
Setting Up Your React Application
Before we dive into implementing dark mode, let’s set up a basic React application. If you haven’t already, you can create a new React app using Create React App:
npx create-react-app dark-mode-example
Once your app is created, navigate into the project directory:
cd dark-mode-example
Adding State Management with Context API
To manage dark mode state effectively, we can leverage React’s Context API. This will allow us to easily share the dark mode state across the component tree without prop drilling. First, let’s create a Context for our dark mode.
Creating the Context
Create a new file named ThemeContext.js in the src directory:
import React, { createContext, useState, useContext } from 'react';
const ThemeContext = createContext();
export const ThemeProvider = ({ children }) => {
const [darkMode, setDarkMode] = useState(false);
return (
{children}
);
};
export const useTheme = () => useContext(ThemeContext);
This code sets up a context with a state variable for dark mode and a function to toggle it.
Wrapping Your Application with the Provider
Next, let’s wrap our entire application in the ThemeProvider. Open src/index.js and modify it as follows:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { ThemeProvider } from './ThemeContext';
ReactDOM.render(
,
document.getElementById('root')
);
Creating the Dark Mode Toggle
Now that we have our context set up, it’s time to create a toggle button for dark mode. Let’s create a simple component named ThemeToggle.js.
import React from 'react';
import { useTheme } from './ThemeContext';
const ThemeToggle = () => {
const { darkMode, setDarkMode } = useTheme();
return (
);
};
export default ThemeToggle;
This button will toggle the dark mode state when clicked.
Using the Button in the Main App
In your App.js file, you can now import and use the ThemeToggle component:
import React from 'react';
import './App.css';
import ThemeToggle from './ThemeToggle';
import { useTheme } from './ThemeContext';
const App = () => {
const { darkMode } = useTheme();
return (
Hello, World!
);
};
export default App;
Styling for Dark Mode
Next, we need to add some styles to our application. Open src/App.css and add styles for both light and dark modes:
body {
margin: 0;
font-family: Arial, sans-serif;
}
.App {
text-align: center;
padding: 20px;
background-color: white;
color: black;
transition: background-color 0.3s ease, color 0.3s ease;
}
.App.dark-mode {
background-color: #121212;
color: #ffffff;
}
With this, our application will respond to the state of dark mode with smooth transitions between styles!
Persisting User’s Preference
It’s essential to save users’ preferences across sessions. For this, we can use the localStorage. Update the ThemeProvider to read from and write to localStorage:
import React, { createContext, useState, useContext, useEffect } from 'react';
const ThemeContext = createContext();
export const ThemeProvider = ({ children }) => {
const [darkMode, setDarkMode] = useState(() => {
const savedMode = localStorage.getItem('darkMode');
return savedMode === 'true' || false;
});
useEffect(() => {
localStorage.setItem('darkMode', darkMode);
}, [darkMode]);
return (
{children}
);
};
export const useTheme = () => useContext(ThemeContext);
Enhancing Dark Mode with CSS Variables
For more flexibility and ease of use, CSS variables can be beneficial when it comes to theming. Let’s modify our styles to use CSS variables.
:root {
--background-light: white;
--background-dark: #121212;
--text-light: black;
--text-dark: #ffffff;
}
.App {
background-color: var(--background-light);
color: var(--text-light);
}
.App.dark-mode {
background-color: var(--background-dark);
color: var(--text-dark);
}
This approach allows for easier theming, especially if you introduce more themed elements in the future.
Conclusion
In this article, we’ve learned how to implement dark mode in a React application using the Context API and localStorage for state management. By providing users with the ability to switch to dark mode, we enhance their experience and cater to their preferences. This is just the beginning; you can expand on this by adding further customization and more complex theming solutions.
As always, happy coding!
