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

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.