zustand로 로그인 전역 상태 관리하기( persist 적용)

타다닥·2024년 2월 25일
3
post-custom-banner

이번 프로젝트에서는 전역 상태 관리 라이브러리로 Zustand를 사용했다.

이런 저런 이유가 있지만 사용하기로 한 이유는

Redux에 비해 가볍고, 불필요한 코드가 적고, 직관적이다! 그리고 프로젝트의 규모도 큰 편이 아니기에 굳이 Redux를 쓸 필요는 없다고 생각했다. 새로운 걸 사용해보고 싶기도 했다!


➡️ 설치하기 (React, TypeScript환경)

npm i zustand

➡️ Type 지정하기

  • TypeScript를 사용중이기 때문에 우선 type을 지정해준다!
type AuthStore = {
  isLoggedIn: boolean;
  login: () => void;
  logout: () => void;

  userId: string | null;
  setUserId: (userId: string) => void;
  userName: string | null;
  setUserName: (userName: string) => void;
  userNickname: string | null;
  setUserNickname: (userNickname: string) => void;
  userNumber: number | null;
  setUserNumber: (userNumber: number) => void;
};

➡️ Store 생성하기, Persist 적용하기

import { createStore } from "zustand";

const useAuthStore = createStore(
  persist<AuthStore>(
    (set) => ({
      isLoggedIn: false,
      login: () => set({ isLoggedIn: true }),
      logout: () =>
        set({
          isLoggedIn: false,
          userId: null,
          userNickname: null,
          userNumber: null,
          userName: null,
        }),
      userId: null,
      setUserId: (userId: string) => set({ userId: userId }),
      userName: null,
      setUserName: (userName: string) => set({ userName: userName }),
      userNickname: null,
      setUserNickname: (userNickname: string) =>
        set({ userNickname: userNickname }),
      userNumber: null,
      setUserNumber: (userNumber: number) => set({ userNumber: userNumber }),
    }),
    {
      name: "userInfoStorage", //Storage 이름 지정 (default: localStorage)
    }
  )
  //)
);
  • 스토어 생성하기 위해 createStore 를 불러온다. import { createStore } from "zustand";
  • login, logout 상태를 구분하기 위해 isLoggedIn: boolean 을 만들어주었다.
  • 그리고 위에서 작성한 AuthStore type을 사용해서 어떻게 상태를 관리할 건지 작성해주면 된다.
    • 그리고 사용자가 로그인 시 서버에서 넘어오는 정보를 저장해주는 함수를 작성해주었다.
    • 전역으로 사용이 필요한 내용들을 저장 해 주는 것!

🥹 하지만 생겨버린 문제점

  • 근데 여기서 로그인 상태를 관리 하더라도 새로고침을 하게 되면 로그아웃이 되어버린다.
  • 그래서 persist 미들웨어를 적용해주었다. zustand에서 제공해준다!
  • 사용법은 그냥 없다..너무 간단하다.. persist 로 감싸주기만 하면 된다!
    • name: "userInfoStorage", 이런식으로 Storage 이름을 지정할 수 있다.
    • 저장 공간은 기본적으로 localStorage 이고,
      storage: createJSONStorage(() => sessionStorage 해주면 세션스토리지로 관리 할 수 있다.

➡️ 로그인 페이지에서 사용하기

//상단에서 사용 할 store를 import 해온다.
import useAuthStore from "../../../stores/useAuthStore";
  

const onSubmit: SubmitHandler<LoginFormInputs> = async (data) => {
    try {
      const res = await axios.post("/api/login", data, {
        headers: {
          "Content-Type": "application/json",
        },
      });
      if (res.status == 200) { //로그인이 성공하면 useAuthStore에 필요한 내용을 세팅!
        useAuthStore.setState({
          isLoggedIn: true,
          userId: res.data.userId,
          userName: res.data.userName,
          userNumber: res.data.userNumber,
          userNickname: res.data.userNickname,
        });
        navigate("/");
      }
    } catch (error) {
      console.log("로그인 err", error);
    }
  };

➡️ 로그아웃 할 때는 이렇게 해주었다.

//로그아웃 요청 성공 시
const logout = useAuthStore.getState().logout;
logout();
//useAuthStore 에서 로그아웃 시 저장된 정보들을 null값으로 초기화시키도록 했기 때문에
//logout상태를 그대로 사용해주기만 하면 된다!
logout: () =>
        set({
          isLoggedIn: false,
          userId: null,
          userNickname: null,
          userNumber: null,
          userName: null,
        }),
profile
프론트엔드 ㄱH발ㅈr ㅎH보ㅈr - ☆
post-custom-banner

1개의 댓글

comment-user-thumbnail
2024년 10월 22일

혹시 여쭤볼게 있는데 개인적으로 연락할 수 있는 연락처를 주실 수 있나요?

답글 달기