[React] Recoil을 이용하여 다크모드 만들기

soyeon·2022년 3월 4일
0

TIL

목록 보기
13/32
post-thumbnail
post-custom-banner

Recoil을 이용하여 state를 관리하고 다크모드를 만들자!!

준비하기

설치

npm install recoil

index.tsx에 RecoilRoot 삽입

ReactDOM.render(
  <React.StrictMode>
    <RecoilRoot>
    {/* // Provide the client to your App */}
    <QueryClientProvider client={queryClient}> 
        <App />
    </QueryClientProvider>
    </RecoilRoot>
  </React.StrictMode>,
  document.getElementById("root")
);

atoms.ts 파일 만들기

  • atom()을 사용하여 state를 집어넣을 공간을 만들어준다.
import { atom } from "recoil";

export const isDarkAtom = atom({
    //state 이름(고유)
    key:"isDark",
    // 기본값
    default: false,
})

atom을 이용해서 state 값 불러오기

  • useRecoilValue : atom의 state을 불러옴
function App() {
  const isDark = useRecoilValue(isDarkAtom);
  return (
    <>
      <ThemeProvider theme={isDark ? darkTheme : lightTheme}>
        <GlobalStyle />
        <Router />
        <ReactQueryDevtools initialIsOpen={true} />
      </ThemeProvider>
    </>
  );
}
  • isDark가 true면 다크모드 / false면 라이트모드

atome의 value 값 수정하기 (state의 값 수정)

  • useSetRecoilState : atom의 state 값을 바꿀 수 있음 (Usestate()의 Setfn을 떠올리면 된다)
function App() {
  const isDark = useRecoilValue(isDarkAtom);
  const setDarkAtom = useSetRecoilState(isDarkAtom);
  const toggleDark = () => setDarkAtom ((prev) => !prev);
  return (
    <>
      <ThemeProvider theme={isDark ? darkTheme : lightTheme}>
        <button onClick={toggleDark}>toggle Mode</button>
        <GlobalStyle />
        <Router />
        <ReactQueryDevtools initialIsOpen={true} />
      </ThemeProvider>
    </>
  );
}
  • 토글 버튼을 누르면 isDark의 값이 정반대로 바뀌도록 함수 작성

Recoil의 장점..

  • state를 전달하려면 컴포넌트 - 하위 컴포넌트 - 하위 컴포넌트의 하위 컴포넌트
    이런 식으로 한단계씩 내려가야하는데 Recoil은 atoms.ts에 state들을 저장하고 필요할 때마다 useRecoilValue, useSetRecoilState를 이용해 꺼내 쓸 수 있음
  • 예시로 App.tsx 말고도 하위의 하위의 하위 컴포넌트인 Chart.tsx에도 isDark atom을 사용하여 ApexChart의 모드를 바꿀 수 있도록 해봤음
    Chart.tsx
function Chart({ coinId }: ChartProps) {
  const isDark = useRecoilValue(isDarkAtom);
  ...
   return(
  ...
<ApexChart
          type="line"
          series={[
            {
              name: "Price",
              data: data?.map((price) => price.close),
            },
          ]}
          options={{
            theme: {
              mode: isDark ? "dark" : "light",
            },
  ...

📎참고

Recoil 공식문서(한국어) - https://recoiljs.org/ko/docs/introduction/installation
React JS 마스터클래스 - 노마드코더 https://nomadcoders.co/react-masterclass

나중에 더 배우면 추가하겠음

profile
공부중
post-custom-banner

0개의 댓글