In this article, i'll implement dark-light mode to a react app.
We will follow those steps:
Create react context hook
Create the context Provider
Provide and use the theme
Step 1: Create react context hook
1import React, { createContext } from 'react'
2
3export enum Modes {
4 DARK = 'dark',
5 LIGHT = 'light',
6}
7
8export const ThemeContext = createContext<{
9 mode: Modes
10 changeMode: () => void
11}>({
12 mode: Modes.LIGHT,
13 changeMode: () => {},
14})
1import React from "react";
2import { ThemeContext } from "./themecontextProvider";
3
4const useDarkLightMode = () => {
5 const context = React.useContext(ThemeContext);
6 return context;
7};
8
9export { useDarkLightMode };
Step 2: Create theme Provider
Create a theme wrapper that will use the created context and pass in the new changes:
1import React, { useEffect, useState } from 'react';
2
3interface CustomStyle {
4 lightColor: string
5 darkColor: string
6}
7
8export const DarkLightModeProvider = (props: {
9 children: React.ReactChildren
10 customStyle: CustomStyle
11}) => {
12
13 const [darkMode, setDarkMode] = useState<boolean>(false)
14
15 const changeTheme = () => {
16 setDarkMode(!darkMode)
17 }
18
19 useEffect(() => {
20 if (typeof window != undefined) {
21 setDarkMode(window.localStorage.getItem('mode') === Modes.DARK)
22 }
23 }, [typeof window])
24
25 useEffect(() => {
26 if (darkMode) {
27 document.body.style.background = props.customStyle.darkColor
28 localStorage.setItem('mode', Modes.DARK)
29 } else {
30 document.body.style.background = props.customStyle?.lightColor
31 localStorage.setItem('mode', Modes.LIGHT)
32 }
33 }, [darkMode])
34
35 return (
36 <ThemeContext.Provider
37 value={{
38 mode: darkMode ? Modes.DARK : Modes.LIGHT,
39 changeMode: () => changeTheme(),
40 }}
41 >
42 {props.children}
43 </ThemeContext.Provider>
44 )
45}
Step 3 : Provide and use the theme
Now that we have our theme set and ready to be used, we’ll add it to the root of our App
1import React, { useState } from 'react'
2import { DarkLightModeProvider } from 'react-dark-light-theme'
3
4const App = () => {
5 const darkLightThemeStyle = { lightColor: '#fff', darkColor: '#000' }
6 return (
7 <DarkLightModeProvider customStyle={darkLightThemeStyle}>
8 <NavBar />
9 </DarkLightModeProvider>
10 )
11}
Step 4: Create a simple toggle button to test the whole things we set up so far
It is ready and used. We now need a toggle button that will trigger the theme change. For this, I’ll start with a simple button to check if everything is working the way we want:
1import React, {useState} from "react";
2import { useDarkLightMode } from 'react-dark-light-theme';
3import NightModeIcon from 'assets/icons/NightModeIcon';
4import LightModeIcon from 'assets/icons/LightModeIcon';
5
6const NavBar = () => {
7 const { mode, changeMode } = useDarkLightMode();
8 return (
9 <div>
10 {mode === 'dark' ? <LightModeIcon/> : <NightModeIcon />}
11 <button type="button" onClick={changeMode}>
12 Change Mode
13 </button>
14 </div>
15 );
16};
When the action is triggered:
I need to switch the dark mode to the opposite color.
Here you can find an npm package where I included the previous implementation.