Dark mode in React using Context

April 23, 2022 - 2 min read

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.

Get in Touch

Via email: ilyass1.ib@gmail.com

Via form