인재재 2025. 2. 3. 17:07

Zustand는 작은 용량, 빠른 속도 그리고 확장 가능성을 자랑하는 상태 관리 라이브러리.

Zustand, redux, context api등 중에서 전역 상태는 어떻게 관리하면 좋을지 고민을 하게 되었다.

 

1. 러닝커브

vanilla js 기준 공식 홈페이지의 20줄 정도의 예시를 읽어도 쉽게 이해 및 적용이 가능할 정도의 완만하게 낮은 러닝커브를 가지고 있다.

 

비교군으로 redux를 사용하여 일정 이상 프로젝트를 진행하면, 많은 보일러플레이트와 복잡도를 중간에 참여한 협업자가 이해하려면 꽤나 큰 리소스가 든다.

 

Redux는 유연한 방식으로 어플리케이션의 상태를 관리하기 위한 고급 기능을 제공하는 강력한 라이브러리이다. 규모가 크고 복잡한 소프트웨어 어플리케이션에서 흔히 사용되며 상태 관리에 보다 강력한 접근이 필요한 경우에 유용하다.

효과적인 사용을 위해 더 많은 설정과 학습을 수반하지만, Redux는 React 뿐만 아니라 다른 시나리오에서도 사용이 가능한 특징을 가지고있다.

 

LOOKY프로젝트에서는 유저의 정보들을 전역적으로 관리할 때와 게시물 업로드시 게시물 목록 Get API를 재호출할 때만 사용하기 때문에 복잡한 상태관리가 필요없었고, Redux는 적합하지 않다고 판단했다.

 

2. 프로바이더 없는 구조

React의 Context API나 Recoil 같은 라이브러리는 앱을 프로바이더로 감싸야 하는 경우가 많다. Zustand는 이러한 제약을 두지 않아서 앱의 렌더링 트리를 단순화시킬 수 있다.  ->  앱을 래핑하지 않아도 되기 때문에 불필요한 리렌더링 최소화

 

3. 커뮤니티와 생태계

Zustand는 빠르게 성장하는 커뮤니티와 활발한 개발 환경을 자랑한다. 이는 버그 수정이나 새로운 기능 추가가 빠르게 이루어지며, 다양한 미들웨어나 확장 기능을 쉽게 찾을 수 있다는 것을 의미한다.

1.16kb라는 번들 사이즈를 가진 Zustand는 용량이 작은 상태 관리 라이브러리들 중 하나입니다. 깃허브에선 50k라는 스타수를 보유하고 있으며 이는 redux, mobX, jotai보다도 높은 스타수이다. Zustand의 단순함과 쉬운 사용성 덕분에 개발자들 사이에서 리액트 앱의 상태 관리 라이브러리로서 점차 유명세를 얻고 있다.

 

https://github.com/pmndrs/zustand

 

import { User } from "@/types/user.types";
import { create } from "zustand";

interface AuthState {
  user: User | null;
  isAuthenticated: boolean;
  login: (user: User) => void;
  logout: () => void;
  restoreSession: () => void;
}

export const useAuthStore = create<AuthState>((set) => ({
  user: null,
  isAuthenticated: false,
  login: (user) => {
    set({
      user,
      isAuthenticated: true,
    });
    localStorage.setItem("user", JSON.stringify(user));
  },
  logout: () => {
    set({
      user: null,
      isAuthenticated: false,
    });
    localStorage.removeItem("user");
  },
  restoreSession: () => {
    const userData = localStorage.getItem("user");
    if (userData) {
      const user: User = JSON.parse(userData);
      set({
        user,
        isAuthenticated: true,
      });
    }
  },
}));

 

 

import { create } from "zustand";

interface ArticleStore {
  ArticleId: string | null;
  setArticleId: (id: string | null) => void;
}

export const useArticleStore = create<ArticleStore>((set) => ({
  ArticleId: null,
  setArticleId: (id) => set({ ArticleId: id }),
}));