포스트

Zustand 상태 설계 가이드

Zustand 상태 설계 가이드

Zustand 상태 설계

정의

  • 애플리케이션의 복잡도에 따라 Zustand 스토어를 구조화하고 상태를 효율적으로 관리하기 위한 설계 방식
  • 단순한 데이터 저장을 넘어 확장성, 유지보수성, 성능을 고려한 아키텍처를 정의한다.

특징

  • 유연한 스토어 구성
    • 하나의 거대한 단일 스토어로 관리하거나, 도메인별로 여러 개의 스토어로 분리할 수 있다.
  • 슬라이스 패턴(Slice Pattern) 지원
    • 여러 개의 작은 상태 조각(Slice)을 정의하고 이를 하나의 메인 스토어로 합성하는 방식을 지원한다.
  • 비정형적 구조
    • Redux와 달리 특정 폴더 구조나 액션 정의 방식이 강제되지 않아 프로젝트 상황에 맞게 커스터마이징이 가능하다.

장점

  • 프로젝트 규모에 맞춰 유연하게 확장 가능하다.
  • 슬라이스 패턴을 통해 도메인별로 로직을 분리하여 코드 가독성을 높일 수 있다.
  • 불필요한 리렌더링을 방지하기 위한 선택적 구독(Selector) 적용이 용이하다.

단점

  • 정해진 규칙이 없으므로 초기 설계 단계에서 팀원 간의 컨벤션 정의가 중요하다.
  • 잘못된 설계로 인해 스토어 간 의존성이 복잡해질 경우 추적이 어려울 수 있다.

설계 패턴 및 가이드

1. 단일 스토어 vs 멀티 스토어

  • 단일 스토어: 프로젝트 전체의 상태를 하나의 스토어에서 관리한다. 상태 간의 참조가 쉬우나 규모가 커지면 관리가 어렵다.
  • 멀티 스토어: 인증(Auth), 사용자 정보(User), 설정(Settings) 등 도메인별로 스토어를 나눈다. 관심사 분리가 명확하지만 스토어 간 데이터를 주고받을 때 추가적인 처리가 필요하다.

2. 슬라이스 패턴 (Slice Pattern)

대규모 프로젝트에서 하나의 스토어를 유지하면서도 코드를 모듈화할 때 사용하는 방식이다.

// counterSlice.ts
export const createCounterSlice = (set) => ({
  count: 0,
  increase: () => set((state) => ({ count: state.count + 1 })),
});

// userSlice.ts
export const createUserSlice = (set) => ({
  name: '',
  setName: (name) => set({ name }),
});

// store.ts
import { create } from 'zustand';
import { createCounterSlice } from './counterSlice';
import { createUserSlice } from './userSlice';

export const useBoundStore = create((...a) => ({
  ...createCounterSlice(...a),
  ...createUserSlice(...a),
}));

3. Flat한 상태 구조 유지

상태 객체가 너무 깊게 중첩(Deeply Nested)되면 업데이트 로직이 복잡해지고 실수할 확률이 높다. 가급적 평탄한(Flat) 구조를 유지하는 것이 좋다.

// Bad: 너무 깊은 중첩
const state = {
  user: {
    profile: {
      settings: {
        theme: 'dark'
      }
    }
  }
};

// Good: 평탄한 구조
const state = {
  userId: 1,
  theme: 'dark',
  isNotificationEnabled: true
};

4. Selector를 통한 최적화

컴포넌트에서 필요한 상태만 골라서 사용함으로써 불필요한 리렌더링을 방지한다.

// 전체 스토어를 구독하지 않고 필요한 것만 선택
const count = useCounterStore((state) => state.count);
const increase = useCounterStore((state) => state.increase);

결론

Zustand는 설계의 자유도가 매우 높다. 소규모 프로젝트에서는 단일 스토어로 빠르게 개발하고, 규모가 커짐에 따라 슬라이스 패턴이나 멀티 스토어 방식을 도입하여 구조화하는 것이 효율적이다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.