지난 번에 했던 크립토 트래커 클론코딩에 recoil을 도입해보았당
일단 리코일 안 쓴 버전을 구현해보며 리코일의 필요성에 대해 느껴보자
//App.tsx
function App() {
return (
<>
<ThemeProvider theme={theme}>
<GlobalStyle />
<Router />
</ThemeProvider>
</>
);
}
⏩ ThemeProvider (index.tsx → App.tsx) 이동
→ state
를 사용하기 위해서!
//theme.ts
export const darkTheme: DefaultTheme = {
bgColor:'black',
textColor:'black',
accentColor:'#fbc531',
}
export const lightTheme: DefaultTheme = {
bgColor:'whitesmoke',
textColor:'black',
accentColor:'#fbc531',
}
➕ lightTheme 추가
//App.tsx
const [isDark, setIsDark] = useState(false);
useState를 사용해서 isDark 기본값 false
const toggleDark = () => setIsDark(current => !current)
isDark: true -> return: false
isDark: false -> return: true
<ThemeProvider theme={isDark ? darkTheme : lightTheme}>
<button onClick={toggleDark}>Toggle Mode</button>
button 클릭시 theme toggle
➕ cf)
const toggledDark = () => setIsDark(!isDark);
이렇게 안하고
const toggledDark = () => setIsDark((current) => !current);
이렇게 하는 이유
: 현재 상태를 사용하려면 함수를 사용하는 것이 좋다
함수를 사용할 경우 React는 이전 값을 그 위치에 배치한다
<Router toggleDark={toggleDark}/>
//Router.tsx
interface IRouterProps {
toggleDark: () => void;
}
function Router({toggleDark}:IRouterProps)
//Coins.tsx
interface ICoinsProps {
toggleDark: () => void;
}
function Coins({toggleDark}: ICoinsProps)
<button onClick={toggleDark}>Toggle Mode</button>
이렇게나 많은 과정을 거쳐서 드디어 toggleDark 함수를 쓸 수 있게 되었다
<Router toggleDark={toggleDark} isDark={isDark} />
interface IRouterProps {
toggleDark: () => void;
isDark: boolean;
}
function Router({toggleDark, isDark}:IRouterProps)
interface ICoinsProps {
toggleDark: () => void;
isDark: boolean;
}
function Coins({toggleDark, isDark}: ICoinsProps)
interface ICoinProps {
isDark: boolean;
}
function Coin({isDark}:ICoinProps)
이걸 계속계속 반복해서 chart까지 내려주면 된다 .. (노가다)
options={{
theme:{
mode: isDark ? "dark" : "light"
},
그럼 이렇게 차트에도 theme이 적용된다
(현재: lightTheme)
global state는 특정 value에 접근할 때 쓰임 → state management (ex. recoil) 사용하면 효율적
state를 따로 buble에 담아서 각 컴포넌트들이 필요할때 buble에 접속해서 사용할 수 있게 함
props 내려주는 대신 atom을 따로 만들어줌
atoms.ts 파일을 만들어서 recoil 사용하기
//atoms.ts
import { atom } from "recoil";
export const isDarkAtom = atom({
key: "isDark",
default: false,
})
//App.tsx
import {useRecoilValue} from 'recoil';
import { isDarkAtom } from './atoms';
const isDark = useRecoilValue(isDarkAtom);
<ThemeProvider theme={isDark ? darkTheme : lightTheme}>
사용 완료!
//Chart.tsx
options={{
theme: {
mode: isDark ? 'dark' : 'light',
},
그럼 이제 Chart.tsx
에서도 import만 한다면 바로 사용 가능하다
const setDarkAtom = useSetRecoilState(isDarkAtom);
useSetRecoilState
: value를 설정하는 함수
const isDark = useRecoilValue(isDarkAtom);
useRecoilState
: value 가져오기