Recoil์ React๋ฅผ ์ํ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค. ์น์ ์ ์ญ์ ์ผ๋ก ํ์ํ ์ํ ๊ด๋ฆฌ๋ฅผ ์ฝ๊ฒ ๋์์ค๋ค.
npm install recoil
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()
์ ์ฌ์ฉํ์ฌkey
์ default
๊ฐ์ ์ ์ํ๋ค.
// atoms.ts
import { atom } from "recoil";
export const isDarkAtom = atom({
key: "isDark",
default: false,
});
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>
);
}