Zustand에서 새로고침 시 user 데이터가 사라지는 문제 해결하기

verdantgreeny·2025년 2월 25일

본캠프

목록 보기
44/56

문제 발생

context API에서 zustand로 리팩토링한 후로 프로필에서 새로고침만 하면 데이터를 불러오지 못하는 문제가 발생했다. 기존에는 Context API를 사용했을 때 이런 문제가 없었지만, Zustand로 상태 관리를 변경한 뒤 새로고침을 하면 프로필 정보가 사라졌다.

원인 추론

정확한 원인을 알기 위해 콘솔창에 유저 정보를 찍어보니 새로고침을 하면 유저가 null이 뜬다는 것을 알게 되었다. 그렇다면 유저가 없을 경우 다시 fetchUserProfile을 호출하면 될것이라 생각하여 아래 코드를 추가하였다.

  useEffect(() => {
    if (!user) {
      fetchUserProfile();
    }
  }, [user, fetchUserProfile]);

이제 새로고침 후에도 데이터를 불러올 수는 있었지만, 계속해서 에러 알림이 뜨는 문제가 발생했다. 조금 더 알아보니, Zustand는 새로고침하면 메모리가 초기화되면서 user 상태도 함께 사라지는 구조였다.

해결 방법

Zustand의 persist 미들웨어를 사용하면 새로고침해도 user 데이터를 유지할 수 있다. 그래서 persist를 적용하여 새로고침 후에도 user 상태가 유지되도록 수정했다.

import { create } from "zustand";
import { getUserProfile } from "../api/auth";
import { persist } from "zustand/middleware";

const useAuthStore = create(
  persist(
    (set, get) => ({
      accessToken: "",
      isAuthenticated: false,
      user: null,

      //사용자가 로그인하면
      authenticateUser: (token) => {
        set({ accessToken: token, isAuthenticated: true }); //상태 업데이트
        get().fetchUserProfile(); //사용자 프로필 정보 가져오기
      },

      //사용자가 로그아웃하면
      logoutUser: () => {
        set({ accessToken: "", isAuthenticated: false, user: null }); //상태 업데이트
      },

      //accessToken을 사용햐 프로필 데이터 가져옴(비동기함수)
      fetchUserProfile: async () => {
        const { accessToken } = get(); //토큰 겟
        if (!accessToken) return;
        try {
          const res = await getUserProfile(accessToken); //api로 데이터 요청
          set({ user: res }); // 성공 시 사용자 정보를 user에 저장
        } catch (error) {
          console.log(error.message);
        }
      },
    }),
    {
      name: "user",
      getStorage: () => localStorage,
      partialize: (state) => ({
        accessToken: state.accessToken,
        isAuthenticated: state.isAuthenticated,
        user: state.user,
      }),
    }
  )
);

export default useAuthStore;

결과

이제 새로고침을 하여도 데이터를 불러오지 못하는 오류가 발생하지 않고 있다.

또한, user 정보가 localStorage에 저장되는 것도 확인할 수 있다.

0개의 댓글