📚 Reference
📜 Chapter
‣
persist 미들웨어를 사용하면 상태를 localStorage 등에 아주 간단하게 저장할 수 있다.import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface UserState {
isLoggedIn: boolean;
login: () => void;
logout: () => void;
}
const useUserStore = create<UserState>()(
persist(
(set) => ({
isLoggedIn: false,
login: () => set({ isLoggedIn: true }),
logout: () => set({ isLoggedIn: false }),
}),
{
name: 'user-storage', // 저장소에 쓰일 고유 키 이름
}
)
);
localStorage이지만, 필요에 따라 설정을 변경할 수 있다.
sessionStorage를 쓰고 싶다면 storage 옵션을 추가한다.{
name: 'app-storage',
// 세션 스토리지 사용 시
storage: createJSONStorage(() => sessionStorage),
// isLoggedIn만 저장하고 나머지는 제외하고 싶을 때
partialize: (state) => ({ isLoggedIn: state.isLoggedIn }),
}
persist는 브라우저의 저장소를 사용하기 때문에, 서버 사이드 렌더링(SSR) 환경에서는 서버와 클라이언트의 초기 데이터가 달라 Hydration Error가 발생할 수 있다.onRehydrateStorage를 활용하거나 클라이언트에서만 렌더링되도록 처리해야 한다.// 상태가 복구되었는지 확인하는 flag를 두는 방식
const useStore = create(
persist(
(set) => ({
data: [],
_hasHydrated: false,
setHasHydrated: (state) => set({ _hasHydrated: state }),
}),
{
name: 'my-store',
onRehydrateStorage: () => (state) => {
state?.setHasHydrated(true);
},
}
)
);
version과 migrate를 사용한다.{
name: 'user-storage',
version: 1, // 버전 번호
migrate: (persistedState: any, version: number) => {
if (version === 0) {
// 구버전 데이터를 신버전 구조로 변환하는 로직
return { ...persistedState, newField: 'default' };
}
return persistedState;
},
}