Как реализовать переключение темы пользовательского интерфейса (темный режим) с помощью React и Recoil

Как реализовать переключение темы пользовательского интерфейса (темный режим) с помощью React и Recoil

Исходный узел: 1781487

ПРИМЕЧАНИЕ. Это руководство актуально для разработчиков, использующих подход к стилю CSS-in-JS, например, Emotion.js, Material UI и т. д.

Шаг 1: Используйте атом отдачи для имени выбранной темы.

import { PaletteMode } from "@mui/material";
import { atom } from "recoil"; export const ThemeName = atom<PaletteMode>({ key: "ThemeName", effects: []
});

Шаг 2: Используйте селектор Recoil для текущего выбранного объекта темы.

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(); },
});

Шаг 3: Добавить useTheme(), useToggleTheme() Реагировать на крючки

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")); }, [] );
}

Шаг 4: Сохраните/восстановите текущее выбранное имя темы в/из 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); }); }, ],
});

Шаг 5: Добавить ThemeProvider к компоненту React верхнего уровня

import { ThemeProvider } from "@mui/material";
import { useTheme } from "../theme/index.js"; function App(): JSX.Element { const theme = useTheme(); return ( <ThemeProvider theme={theme}> {/* ... */} </Theme> );
}

Читать app/theme/index.ts in Стартовый набор React

Полезные ресурсы

Отметка времени:

Больше от Codementor Реагировать Факт