사이드 프로젝트 상태 관리 라이브러리 Zustand 적용기

JH.P·2024년 7월 16일

적용 배경

  • 현재 진행 중인 프로젝트가 점점 디벨롭을 거듭하며 컴포넌트의 갯수가 많아지고, Depth가 깊어지며 Props Drilling 현상이 생기기 시작했다.
  • 기존엔 최상위 컴포넌트에서 로그인 및 다크모드 상태를 관리했는데, 다크모드 상태를 필요로 하는 몇몇 컴포넌트가 최상위 컴포넌트와의 Depth 차이가 많이 났을 뿐더러, 추후를 위해서라도 상태 관리 라이브러리를 도입하는 것이 좋을 것이라 생각하였다.
  • 보일러 플레이트가 크지 않고, 무엇보다 상태 관리에 많은 시간을 쏟지 않고 메인 로직에 집중하고 싶었다.
  • 그 중 zustand를 살펴보게 되었고, 사용이 간편하며 상태 저장 및 관리하는 구조도 마음에 들었고, Provider 작성이 불필요하며 비효율적인 리렌더링을 최소화할 수 있어, 추후 성능 최적화하는 데도 이점이 될 것 같아 채택하게 되었다.

기본 사용 예시

  • 공식 문서에 의하면 아래와 같이 사용 가능하다.
import { create } from 'zustand'

const useStore = create((set) => ({
  count: 1,
  inc: () => set((state) => ({ count: state.count + 1 })),
}))

function Counter() {
  const { count, inc } = useStore()
  return (
    <div>
      <span>{count}</span>
      <button onClick={inc}>one up</button>
    </div>
  )
}
  • 보다시피 매우 단순하다. 이전에 재직하던 회사에서 Redux를 사용했었는데 상태 관리하는 코드가 정말 방대해서 파악하는데만 많은 시간이 소요됐던 기억이 난다.. 이렇게 간편하게 상태 관리를 할 수 있다는 데에 오픈소스 개발자들에게 감사하다는 생각이 들었다.

적용

  • 나는 로그인, 다크모드 상태를 아래와 같이 전역 상태 관리하였다.
/** 로그인 전역 상태 및 상태 갱신 함수 */
import { create } from "zustand";

interface AuthState {
  isLoggedIn: boolean;
  loginSuccess: (token: string) => void;
  logOut: () => void;
}

const useAuthStore = create<AuthState>((set) => ({
  isLoggedIn: localStorage.getItem("token") ? true : false,
  loginSuccess: (token: string) => {
    localStorage.setItem("token", token);
    set((state) => ({ isLoggedIn: true }));
  },
  logOut: () => {
    localStorage.removeItem("token");
    set((state) => ({ isLoggedIn: false }));
  },
}));

export default useAuthStore;
/** themeMode 전역 상태 및 상태 갱신 함수 */
import { create } from "zustand";
import theme from "../styles/layout/themes";
import { getInitialTheme } from "../utils/themeUtils";

interface ThemeStore {
  themeMode: keyof typeof theme;
  changeTheme: () => void;
}

const useThemeStore = create<ThemeStore>((set, get) => ({
  themeMode: getInitialTheme(),
  changeTheme: () => {
    const newTheme = get().themeMode === "light" ? "dark" : "light";
    localStorage.setItem("themeMode", newTheme);
    set({ themeMode: newTheme });
  },
}));

export default useThemeStore;
  • 사용 예시
  /** 로그인 전역 상태 */
  const { isLoggedIn } = useAuthStore();

  /** theme 전역 상태 */
  const { themeMode, changeTheme } = useThemeStore();
  • 외부 컴포넌트에서 위와 같이 import하여 사용하면 끝. 정말 감탄스럽다.

후기

  • 다양한 종류의 오픈소스 상태관리 라이브러리들이 존재하지만, 이번에 zustand를 도입 및 사용하며 상태 관리에 많은 시간을 쏟지 않으니 메인 로직에 더욱 집중할 수 있었다.
  • 추후 zustand의 동작 원리 및 특징에 대한 자세한 글을 작성하려 한다.
profile
꾸준한 기록

0개의 댓글