새로 고침 후에도 전역상태 유지하기 (Zustand persist)

rada·2025년 8월 15일
0

개발

목록 보기
50/53

기존에 프로젝트를 진행할 때, 로그인 여부를 확인하기 위한 userId를 LocalStorage에 저장하여 관리하였었다.하지만, 상태관리 라이브러리인 Zustand를 도입하면서 userId도 Zustand를 통해 관리하는 것이 좋다고 판단하였다.그래서 userId를 store에서 관리하도록 코드를 수정해 보았다.

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

이것을 해결하기 위해 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으로는

  • name:이것이 유일하게 필요한 옵션이며, 제공된 이름은 저장소에 Zustand 상태를 저장하는 데 사용되는 키가 되므로 고유해야 한다.
  • storage
    - 유형: () => StateStorage
import { StateStorage } from 'zustand/middleware'
- 기본: createJSONStorage(() => localStorage)

자체 저장소를 사용할 수 있고 사용할 저장소를 반환하는 함수를 전달하기만 하면 된다. 인터페이스 를 준수하는 객체를 createJSONStorage생성하려면 도우미 함수를 사용하는 것이 좋다 .storageStateStorage

persist storage 초기화

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

profile
So that my future self will not be ashamed of myself.

0개의 댓글