[Zustand] persist: 페이지 새로고침 시 상태 초기화 방지

KJA·2024년 2월 20일
0
export const useStore = create<UserState>(set => ({
  user: null,
  setUser: (user: User) => set(() => ({ user })),
  updateUser: (id, updates) =>
    set(state => {
      if (state.user?.id === id) {
        return { ...state, user: { ...state.user, ...updates } };
      }
      return state;
    }),
  removeUser: () => set(() => ({ user: null })),
}));

export default useStore;

위는 user의 전역 상태 코드이다.

문제 상황

페이지 새로 고침시에 user가 초기화가 되어버려 null이 출력되는 문제가 발생했다.

원인

대부분의 전역 상태 관리 라이브러리는 상태를 메모리에 유지한다. 페이지가 새로 고쳐지면 JavaScript 환경이 다시 초기화 되어 모든 메모리 내 상태(Zustand store 포함)가 재설정되기 때문에 user에 null이 출력이 되었던 것이었다.

해결

Zustand의 persist를 이용했다. persist는 전역 상태 관리 라이브러리의 기능 중 하나로, 상태의 지속성을 관리하는 데 사용된다. 브라우저가 재시작되거나 페이지가 새로고침될 때도 어플리케이션의 상태를 유지하도록 한다. persist 기능을 사용하면 특정 상태를 로컬 스토리지, 세션 스토리지 같은 저장 공간에 저장하여, 어플리케이션이 재시작되어도 그 상태를 복원할 수 있다.

zustand persist 사용

import { create } from 'zustand';
import { createJSONStorage, persist } from 'zustand/middleware';
import { User } from '../utils/types';

interface UserState {
  user: User | null;
  setUser: (user: User) => void;
  updateUser: (
    id: number,
    updates: Partial<Pick<User, 'name' | 'email'>>,
  ) => void;
  removeUser: (id: number) => void;
}

export const useStore = create(
  persist<UserState>(
    (set, get) => ({
      user: null,
      setUser: (user: User) => set(() => ({ user })),
      updateUser: (id, updates) =>
        set(state => {
          if (state.user?.id === id) {
            return { ...state, user: { ...state.user, ...updates } };
          }
          return state;
        }),
      removeUser: () => set(() => ({ user: null })),
    }),
    {
      name: 'userStorage', // name of the item in the storage (must be unique)
      storage: createJSONStorage(() => sessionStorage), // (optional)이기 때문에 해당 줄을 적지 않으면 'localStorage'가 기본 저장소로 사용된다.
    },
  ),
);

export default useStore;

0개의 댓글