3주차 과제 : 노마드코더 5. STATE MANAGEMENT 수강
ThemeProvider를 index.tsx에서 App 컴포넌트로 끌고온 후, theme을 두개 각각 만들어주면 됨.
function App(){
const [isDark, setIsDark] = useState(true);
return (
<>
<ThemeProvider theme={isDark ? darkTheme : lightTheme}>
...
const toggleDark = ()=> setIsDark(current => !current);
이제 버튼을 하나 만들고 onClick
으로 위 toggle함수를 지정해주면!
그 버튼을 클릭할 때마다 state가 바뀐다.
즉, 테마가 바뀐다
다른 컴포넌트들로 isDark의 state값을 전달하고싶다면,
혹은 toggle함수를 설정할 수 있게 하고 싶다면
Router로 보내주어 props로 타고타고 전달하면 된다.
현재는 App에 isDark와 toggle함수가 있고
이 App이 Router로, Router가 Coins로 함수를 보낸다.
그리고 App은 Router로, Coin으로, 마지막으로 Chart로 isDark를 보낸다.App(isDark, toggleFn) → Router → Coins(toggleFn) → Router → Coin → Chart(isDark)
global state
는 isDark처럼 App 전체에서 공유되는 state이다.
즉, App이 component가 어디에 있든, 누가 접근하려고 하든 관계없이 특정 value에 접근 or 수정해야할 때 사용한다.
예를 들어 유저의 로그인 여부를 isLoggedIn, setIsLoggedIn
이라는 state로 만들어 관리한다고 하면 이 state는 모든 컴포넌트에 공유되어져야하겠지?
이런 state가 바로 global state
이다.
만약 state management
를 사용한다면,
우리는 일종의 비눗방울을 형성할 수 있다. (isDark)
그리고 누군가 isDark를 원한다면 어떤 곳에서든 isDark를 가져갈 수 있게 되는 것이다.
즉, 우리가 원래 사용하던 계층구조(부모→자식) 대신,
state를 어떤 비눗방울 안에 넣고 접근할 수 있게 하는 것이다.
props를 계속해서 내려보내지 않아도 isDark
에 직접 접근할 수 있는 것이다.
React JS에서
state management
를 위한 해결책
→ state를 atom에 넣어서 관리하게 하는 library
Recoil
을 이용하면 props를 통해 필요한 곳으로 계속해서 내려보내는 것 대신, 우리가 위에서 말한 비눗방울을 형성해 직접 값에 접근할 수 있게 할 수 있다.
이러면 value가 필요한 컴포넌트만 그 value를 갖게 된다.
우리는 결과적으로 Chart에서만 isDark값을 필요로 하는데, 현재는 어쩔 수 없이 Router와 Coin을 거치고 있다.
이 효율성 문제를 해결할 수 있는 것이다.
Recoil
에서는 그 비눗방울을 atom
이라고 부른다.
atom
에는 원하는 값을 저장할 수 있다.
어떤 컴포넌트에서 어떤 value에 접근하려면, 그 컴포넌트를 직접 atom
에 연결하면 된다.
이렇게 해주면 우리는 global state
를 훨씬 효율적인 방법으로 관리할 수 있게 된다!
터미널에
npm install recoil
입력
index.tsx
로 가서
...
root.render(
<RecoilRoot>
<QueryClientProvider client={queryClient}>
<App/>
</QueryClientProvider>
</RecoilRoot>
);
...
이렇게 감싸주자.
이제 routes 폴더 내에 atoms.ts
파일을 만들어주고
그 안에 atom들을 만들어준다.
import {atom} from "recoil"; //import 필요
export const isDarkAtom = atom({
key:"isDark",
default: false,
});
그 후에 App.tsx에 가서
useRecoilValue
와 isDarkAtom
을 각각 import 해준 뒤,
const isDark = useRecoilValue(isDarkAtom);
해주면 이제 우리 App과 isDarkAtom
은 연결되었다.
동일한 방법으로 Chart도 연결해준다.
정말 신세계,,
👏👏👏
이제 버튼을 누르면 atom이 수정되도록 해보자.
<Coins.tsx>
...
const setDarkAtom= useSetRecoilState(isDarkAtom);
//물론 import 필요
...
해주자.
setDarkAtom
은 이제 value를 설정해주는 함수로 작동한다.
이 function은 리액트의 setState
와 같은 방식으로 작동한다.
이제 이 setterFn을 버튼에 onClick
으로 주면 되겠지
<button onClick={()=>setDarkAtom((prev) => !prev)}>Toggle Mode</button>
setState
쓰는 것처럼 저런식으로 사용해주면 된다.
이제 버튼을 클릭하면 dark모드와 light모드가 변경된다.
엄청나다...