프로젝트에서 사용할 기술 스택을 결정할 때 가장 고민했던 것이 상태관리 라이브러리였다. 이전 프로젝트에서는
redux-toolkit
을 사용하였는데, 공감병동 프로젝트에서는 전역으로 상태관리를 해야하는 것이 user 밖에 없었기에 좀 더 가벼운 라이브러리를 찾기로 했다.
다양한 시도와 시행착오(실제로 프로젝트 진행 기간 중 약 2일 정도를 팀원과 함께 상태관리에 대해 공부하는데 쓰기도 했다...) 끝에 선택하게 된 것이 Recoil
이었다.
RTK에 비해 가볍고 간단하다!
위에서 언급한 것처럼 전역 상태관리의 필요성이 크지 않았기 때문에 정말 가벼운 라이브러리를 원했다. 또한 Recoil
에 대해 알아보았을 때 사용방법도 간단했어서 Recoil
이 시간에 쫒기던 우리에게 최적의 선택이었다.
npm install recoil
설치가 끈난 후 app.tsx에 모든 컴포넌트를 RecoilRoot 태그로 감싸주었다.
//app.tsx
import type { AppProps } from "next/app";
import { RecoilRoot } from "recoil";
function MyApp({ Component, pageProps }: AppProps) {
return (
<RecoilRoot>
<Component {...pageProps} />
</RecoilRoot>
);
}
export default MyApp;
atom은 상태(state)의 일부를 나타내는데, 우리는 관리가 필요한 전역상태가 user 뿐이어서 파일명을 atom.ts로 만들어주었고, recoilPersist를 활용해 값을 기억해 주었다.
// atom.ts
import { atom } from "recoil";
import { recoilPersist } from "recoil-persist";
const { persistAtom } = recoilPersist();
export const userState = atom({
key: "userState",
default: {
accessToken: "",
isLogin: false,
description: "",
id: 0,
img: "",
loginType: "",
nickname: "",
social_id: "",
...
},
effects_UNSTABLE: [persistAtom],
});
export const drawerState = atom({
key: "drawerState",
default: false,
});
export const loginModalState = atom({
key: "loginModalState",
default: false,
});
위의 방법으로 만든 atom은 각 페이지에서 필요에 따라 원하는 값을 저장하기, 불러오기, 수정하기 등이 가능하다.
import { useRecoilState, useSetRecoilState } from "recoil";
import { userState, loginModalState } from "../../state/atom";
...
const [isLoginModalOpen, setIsLoginModalOpen] =
useRecoilState(loginModalState);
const setUser = useSetRecoilState(userState);
useEffect(() => {
const login = async () => {
if (code) {
const userInfo = await socialLogin(code, state);
setUser({ ...userInfo, isLogin: true });
router.push("/");
}
};
...
}, []);
위의 코드는 로그인 후 유저 정보를 저장하는 과정을 완전 축약한 코드인데,
요약하자면 setUser
를 통해 서버에서 받은 user 데이터를 넣어주고,
isLogin을 true로 바꾸어 로그인을 성공시켜 준 것이다.
//createPost
import { useRecoilValue } from "recoil";
import { userState } from "../../state/atom";
const { accessToken, id } = useRecoilValue(userState);
atom에 저장한 user의 정보는 다른 페이지에서 가져와 사용할 수 있다.
가장 간단한 예로는, 게시글 작성 페이지에서 데이터 패칭에 필요한 accessToken
과 id
만을 가져와 사용하였다.
제대로 공부할 시간 없이 구현을 위해 빠르게 적용시켜 보았는데, 추후에 프로젝트가 끝나면 좀 더 제대로 공부해야겠다.