Codementor Events

How to implement UI theme switching (dark mode) with React and Recoil

Published Aug 03, 2022Last updated Aug 04, 2022
How to implement UI theme switching (dark mode) with React and Recoil

NOTE: This tutorial is relevant to developers using a CSS-in-JS styling approach, e.g. Emotion.js, Material UI, etc.

Step 1: Use Recoil atom for the currently selected theme's name

import { PaletteMode } from "@mui/material";
import { atom } from "recoil";

export const ThemeName = atom<PaletteMode>({
  key: "ThemeName",
  effects: [/* ... */]
});

Step 2: Use Recoil selector for the currently selected theme object

import { createTheme } from "@mui/material";
import { selector } from "recoil";

export const Theme = selector({
  key: "Theme",
  dangerouslyAllowMutability: true,
  get(ctx) {
    const name = ctx.get(ThemeName);
    return createTheme(/* ... */);
  },
});

Step 3: Add useTheme(), useToggleTheme() React hooks

import { useRecoilValue, useRecoilCallback } from "recoil";

export function useTheme() {
  return useRecoilValue(Theme);
}

export function useToggleTheme() {
  return useRecoilCallback(
    (ctx) => () => {
      ctx.set(ThemeName, (prev) => (prev === "dark" ? "light" : "dark"));
    },
    []
  );
}

Step 4: Save/restore the currently selected theme name to/from localStorage

export const ThemeName = atom<PaletteMode>({
  key: "ThemeName",
  effects: [
    (ctx) => {
      const storageKey = "theme";

      if (ctx.trigger === "get") {
        const name: PaletteMode =
          localStorage?.getItem(storageKey) === "dark"
            ? "dark"
            : localStorage?.getItem(storageKey) === "light"
            ? "light"
            : matchMedia?.("(prefers-color-scheme: dark)").matches
            ? "dark"
            : "light";
        ctx.setSelf(name);
      }

      ctx.onSet((value) => {
        localStorage?.setItem(storageKey, value);
      });
    },
  ],
});

Step 5: Add ThemeProvider to the top-level React component

import { ThemeProvider } from "@mui/material";
import { useTheme } from "../theme/index.js";

function App(): JSX.Element {
  const theme = useTheme();

  return (
    <ThemeProvider theme={theme}>
      {/* ... */}
    </Theme>
  );
}

See app/theme/index.ts in React Starter Kit

Resources

Discover and read more posts from Konstantin Tarkus
get started
post comments1Reply
Peter Alvex
2 years ago

To implement UI theme switching with React and Recoil, you can create a Recoil atom to store the current theme and a theme provider component that uses the stored theme to apply styles.

To enable dark mode, you can add a button or toggle that triggers a function to update the theme atom’s value to β€œdark.” The theme provider will then apply the appropriate styles based on the selected theme.

As an example, you can use the https://apkbounce.com/grimvalor-mod-apk/ link to demonstrate the UI theme switching in action. When the user selects the dark mode option, the theme provider will apply dark-themed styles to the page, providing a visually appealing experience.

Note that this is a high-level overview of the implementation process, and actual implementation may require more specific details and customization to suit your particular use case.