기존에 프로젝트를 진행할 때, 로그인 여부를 확인하기 위한 userId를 LocalStorage에 저장하여 관리하였었다.하지만, 상태관리 라이브러리인 Zustand를 도입하면서 userId도 Zustand를 통해 관리하는 것이 좋다고 판단하였다.그래서 userId를 store에서 관리하도록 코드를 수정해 보았다.
import { create } from 'zustand';
type userStore = {
userId: number | null;
setUserId: (newUserId: number) => void;
}
const useUserStore = create<userStore>((set) => ({
userId: null,
setUserId: (newUserId: number) => set(() => { userId: newUserId })),
}));
export default useUserStore;
위와 같이 store를 만들고, 컴포넌트에서 userId를 필요로 할 때마다 LocalStorage가 아닌 store에서 불러올수 있도록 코드를 수정했다.
처음엔 코드가 잘 수정된 줄 알았지만, 한가지 문제가 생겼다.
바로 새로 고침을 하면 로그인 상태가 유지되지 않는다는 것이다.
LocalStorage는 브라우저를 닫아도 정보가 유지되어 로그인 여부를 확인할 수 있었다.
하지만, zustand를 포함한 대부분의 전역 상태 관리 라이브러리들은 상태를 메모리에 유지한다.
그래서 페이지가 새로 고침 되면 javascript 환경이 초기화되어 이전에 저장해 둔 데이터가 사라져 로그인 여부를 확인할 수 없었다.
이것을 해결하기 위해 zustand의 persist를 도입해 보았다.
persist는 zustand의 미들웨어인데, 상태를 LocalStorage와 같은 저장소에 저장하여 데이터를 유지할 수 있도록 해준다.
import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
type userIdStore = {
userId: number | null;
setUserId: (newUserId: number) => void;
}
const useUserStore = create(
persist<userIdStore>(
(set, get) => ({
userId: null,
setUserId: (newUserId: number | null) => set(() => ({ userId: newUserId })),
}),
{
name: 'userIdStorage', // name of the item in the storage (must be unique)
storage: createJSONStorage(() => sessionStorage), //(optional) by default, 'localStorage' is used
},
),
)
export default useUserStore;
Option으로는
import { StateStorage } from 'zustand/middleware'
- 기본: createJSONStorage(() => localStorage)
자체 저장소를 사용할 수 있고 사용할 저장소를 반환하는 함수를 전달하기만 하면 된다. 인터페이스 를 준수하는 객체를 createJSONStorage생성하려면 도우미 함수를 사용하는 것이 좋다 .storageStateStorage
persist를 사용하면 LocalStorage와 마찬가지로 clear를 하고, userId값을 null로 변경해야 로그아웃 후에 storage에 남아 있는 userId를 초기화 할 수 있다.
import useUserStore from '@store/useUserStore';
const clearUserIdStorage = useUserStore.presist.clearStorage;
const handleSignOut = async() => {
const isLogout = await logout();
if (isLogout){
setUserId(0);
clearUserIdStorage();
navigate('/login');
}
}
userId를 먼저 null으로 초기화하고, clearStorage를 통해 storage를 초기화하여 로그아웃을 시킬 수 있었다.
참고:
https://docs.pmnd.rs/zustand/integrations/persisting-store-data
https://velog.io/@dpldpl/Zustand-persist-페이지-새로고침-시-전역상태-초기화-방지-문제-해결
https://surpise.tistory.com/9