darkmode, lightmode 테마를 적용하기 위해선 global state가 필요하다. 기존에는 한 파일에 theme state를 작성하고 그 state를 router에 전달한 후 router에서 다시 theme 적용이 필요한 파일 까지 theme state를 전송해 줬다.
현재는 적은 코드로 만드는 간단한 어플리케이션이기 때문에 꼬리에 꼬리를 무는 state 전달 방식이 큰 무리는 없지만 만약 코드가 길어지고 복잡해질 경우 state 전달만을 위해 유사한 코드를 복사 붙여넣기 하는 방법은 비효율적이다.
따라서 코드 복붙이 필요없는 theme 적용을 위해 recoil을 사용한다.
recoil은 일종의 bubble(Atom)을 만들어서 그 안에 공통적으로 사용해야하는 global variable과 state를 넣어놓는다. 만약 그 변수와 state가 필요하면 Atom을 연결해서 상태를 받아오거나 상태를 변화시킬수 있게 하는 라이브러리 이다.
먼저 npm install
npm install recoil
그리고 전역변수를 넣을 bubble(Atom) 파일을 만든다
import { atom } from 'recoil';
export const isDarkAtom = atom({
key: 'isDark',
default: true,
});
import { useRecoilValue } from 'recoil';
import { isDarkAtom } from './atoms';
...
function App() {
const isDark = useRecoilValue(isDarkAtom);
bubble(Atom)이 필요한 파일에 recoil import, useRecoilValue로 atom.ts의 isDarkAtom을 사용한다고 선언하면 된다.
import { isDarkAtom } from '../atoms';
...
function Coins() {
const setDarkAtom = useSetRecoilState(isDarkAtom);
const toggleDarkAtom = () => setDarkAtom((prev) => !prev);
...
<button onClick={toggleDarkAtom}>Toggle Mode</button>
useSetRecoilState는 기존 isDarkAtom의 상태를 변화할수있는 함수이다. 기존 theme을 prev로 받고 Toggle Mode 버튼을 누르면 !prev로 상태를 바꿔서 버튼을 누르면 화면 전체의 theme을 바꾸게 된다.