React | Recoil

Jiseongยท2023๋…„ 1์›” 10์ผ
0

react

๋ชฉ๋ก ๋ณด๊ธฐ
3/5

๐Ÿ”ฅ Intro

Recoil์€ React๋ฅผ ์œ„ํ•œ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. ์›น์— ์ „์—ญ์ ์œผ๋กœ ํ•„์š”ํ•œ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ์‰ฝ๊ฒŒ ๋„์™€์ค€๋‹ค.

๐Ÿ”ฅ Install

npm install recoil

๐Ÿ”ฅ RecoilRoot

recoil ์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” ๋ถ€๋ชจ ํŠธ๋ฆฌ ์–ด๋”˜๊ฐ€์— ๋‚˜ํƒ€๋‚˜๋Š” RecoilRoot๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
<Root />๋ฅผ <RecoilRoot>๋กœ ๊ฐ์‹ธ์ค€๋‹ค.

// index.tsx

import React from "react";
import ReactDOM from "react-dom/client";
import { QueryClient, QueryClientProvider } from "react-query";
import { RouterProvider } from "react-router-dom";
import router from "./Router";
import Root from "./Root";
import { HelmetProvider } from "react-helmet-async";
import { RecoilRoot } from "recoil";

const queryClient = new QueryClient();

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);

root.render(
  <React.StrictMode>
    <HelmetProvider>
      <RecoilRoot>
        <QueryClientProvider client={queryClient}>
          <RouterProvider router={router} />
          <Root />
        </QueryClientProvider>
      </RecoilRoot>
    </HelmetProvider>
  </React.StrictMode>
);

๐Ÿ”ฅ Atom

Atom์€ ์ƒํƒœ์˜ ์ผ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. ์ปดํฌ๋„ŒํŠธ ์–ด๋””์—์„œ๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. atom์— ๋ณ€ํ™”๊ฐ€ ์žˆ์œผ๋ฉด atom ๊ฐ’์„ ์ฝ๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋“ค์€ ์žฌ ๋žœ๋”๋ง ๋œ๋‹ค.

โœจ atom ์ •์˜

์ „์—ญ์ ์œผ๋กœ ์‚ฌ์šฉํ•  atom์„ ์ •์˜ํ•œ๋‹ค. atom()์„ ์‚ฌ์šฉํ•˜์—ฌkey์™€ default ๊ฐ’์„ ์ •์˜ํ•œ๋‹ค.

// atoms.ts

import { atom } from "recoil";

export const isDarkAtom = atom({
  key: "isDark",
  default: false,
});

โœจ useRecoilState()

atom ๊ฐ’์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” useRecoilState()๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

const [isDark, setIsDark] = useRecoilState(isDarkAtom);

์•„๋ž˜์—์„œ๋Š” useRecoilValue(), useSetRecoilState()์„ ์‚ฌ์šฉํ•˜์—ฌ isDark, setIsDark ์ค‘ ํ•˜๋‚˜์˜ ๊ฐ’๋งŒ ๊ฐ€์ ธ์™”๋‹ค.
isDark ๊ฐ’๊ณผ <ThemeProvider>๋ฅผ ์‚ฌ์šฉํ•ด dark mode, light mode๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

// Root.tsx

import { Outlet } from "react-router-dom";
import { ThemeProvider } from "styled-components";
import { ReactQueryDevtools } from "react-query/devtools";
import { darkTheme, lightTheme } from "./theme";
import { GlobalStyle } from "./screens/css/global";
import { useRecoilValue } from "recoil";
import { isDarkAtom } from "./atoms";

function Root() {
  const isDark = useRecoilValue(isDarkAtom);

  return (
    <ThemeProvider theme={isDark ? darkTheme : lightTheme}>
      <GlobalStyle />
      <Outlet context />
      <ReactQueryDevtools />
    </ThemeProvider>
  );
}

export default Root;
// components/Header.tsx

export default function Header({ children }: { children: ReactNode }) {
  const setIsDark = useSetRecoilState(isDarkAtom);
  const toggleDarkAtom = () => setIsDark((cur) => !cur);

  return (
    <Cotainer>
      <Home>
        <Link to="/">
          <FontAwesomeIcon icon={faHouse} />
        </Link>
      </Home>
      {children}
      <button onClick={toggleDarkAtom}>light/dark</button>
    </Cotainer>
  );
}

0๊ฐœ์˜ ๋Œ“๊ธ€