Recoil로 UI 테마 전환을 구현하는 방법은 무엇입니까?

10789 단어

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



1단계: 현재 선택한 테마 이름에 Recoil atom 사용




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

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


2단계: 현재 선택한 테마 개체에 반동 선택기 사용




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() React 후크 추가




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단계: 최상위 React 구성 요소에 ThemeProvider 추가




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 React Starter Kit 참조

자원


  • https://recoiljs.org/
  • https://learnrecoil.com/course

  • 좋은 웹페이지 즐겨찾기