Recoil: state management library. (cf. redux)

State Management가 필요한 이유

without Recoil

theme.ts

import { DefaultTheme } from "styled-components";

export const darkTheme: DefaultTheme = {
  bgColor: "#2f3640",
  textColor: "white",
  accentColor: "#9c88ff",
  cardBgColor: "transparent",
};

export const lightTheme: DefaultTheme = {
  bgColor: "whitesmoke",
  textColor: "black",
  accentColor: "#9c88ff",
  cardBgColor: "white",
};
function App() {
  const [isDark, setIsDark] = useState(false);
  const toggleDark = () => setIsDark((current) => !current);
  return (
    <> 
    <ThemeProvider theme={isDark ? darkTheme : lightTheme}>
      
      <GlobalStyle />
      <Router isDark={isDark} toggleDark={toggleDark} />

styled-component+TS로 작성한 theme은 다음과 같다.
두 개의 theme은 Coins.tsx 파일에서의 버튼 클릭으로 전환하도록 작성되어있다. 이를 Coin 페이지 안에서 중첩 라우팅 되어있는 Chart.tsx 속 ApexChart의 props에 반영하려고 한다.

현재 파일구조가 이러하기 때문에 Coin 페이지 안의 Chart에서 theme을 전환하기 위해서는 다음과 같은 단계를 거쳐야 한다.

  1. App에서 Router로 toggleDark function을 보낸다.
  2. Router가 Coin으로 toggleDark function을 보낸다.
  3. Coin가 function을 받아 Chart로 보낸다.
  4. Chart가 일련의 과정을 거쳐 theme을 전환한다.

Router.tsx

아래는 function 전송의 예시. (오잉 boolean으로 Coin에 전송했네.. 둘 다 보면 될 것 같다.)

interface IRouterProps {
  toggleDark: () => void;
  //TS에서 function 전송은 이렇게 (parameter/return 없음)
  isDark: boolean;
}

function Router({ toggleDark, isDark }: IRouterProps) {

  return (
    <BrowserRouter>
      <Switch>
        <Route path="/:coinId">
          <Coin isDark={isDark} />
        </Route>
        <Route path="/">
        <Coins toggleDark={toggleDark} />

딱 봐도 귀찮다.
이것은 state가 위치에 구애받기 때문이다.
위치에 상관없이 전역적으로 사용하는 state가 global state다.

with Recoil

Recoil에서는 이런 global state를 atom이라고 한다. Recoil Atom은 한 컴포넌트에 직접 연결되지 않기 때문에 어디서든 직접 access 해서 사용하면 된다.

atom: 만드는 법

key와 default값만이 필요하다.

atom.ts

import { atom } from "recoil";

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

useRecoilValue: 쓰는 법

위에서 생성한 atom을 사용하기 위해서는 useRecoilValue를 사용하면 된다.

App.tsx

~
import { useRecoilValue } from "recoil";
import { isDarkAtom } from "./atoms";
~
function App() {
  const isDark = useRecoilValue(isDarkAtom);
  return (
    <>
      <ThemeProvider theme={isDark ? darkTheme : lightTheme}>
        ~
      </ThemeProvider>
    </>
    );
}
	

useSetRecoilState: 수정하는 법

setState와 같은 방식으로 사용한다. 아래는 theme을 전환하는 버튼이다.

Coins.tsx

const setDarkAtom = useSetRecoilState(isDarkAtom);
const toggleDarkAtom = () => setDarkAtom((prev) => !prev);
return(
~
<button onClick={toggleDarkAtom}>Toggle Mode</button>

0개의 댓글

Powered by GraphCDN, the GraphQL CDN