← 홈페이지 5강 목록으로
🗂️
EPISODE 08
전역 상태 · Zustand · slice · devtools

상태 관리 라이브러리 (Zustand)

전역 상태가 필요한 시점, Zustand vs Redux 비교, create로 store 만들기, 선택적 구독으로 성능 최적화, slice 패턴, devtools 미들웨어를 익힙니다.

Zustand전역 상태Redux
소요 시간
45~60분
난이도
📊 중급~고급
선수 조건
🎯 react-07
결과물
Zustand로 만든 cart/user 전역 store

이 강의에서 배우는 것

  • 1전역 상태가 필요한 시점을 판단한다
  • 2Zustand와 Redux의 차이를 안다
  • 3create로 store를 만들고 set으로 상태를 변경한다
  • 4선택자로 필요한 상태만 구독해 리렌더링을 줄인다
  • 5slice 패턴으로 관심사를 분리한다
  • 6devtools 미들웨어로 디버깅한다

1. 전역 상태가 필요한 시점

상황해결책
컴포넌트 내부useState
부모-자식 전달props
2~3단계 이상 props drillinguseContext
여러 페이지/컴포넌트 공유전역 상태 관리
복잡한 비동기 + 공유 상태전역 상태 관리

장바구니, 로그인 사용자 정보, 알림, 언어 설정 등이 전형적.

2. Zustand vs Redux

항목ZustandRedux Toolkit
설치 크기~1KB큰 편
학습 곡선낮음높음
보일러플레이트거의 없음어느 정도
DevTools미들웨어로기본 내장
비동기자유롭게createAsyncThunk
적합 규모소~중대규모 팀

3. Zustand 기본

bash
npm install zustand
jsx
import { create } from 'zustand';

const useCounterStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  decrement: () => set((state) => ({ count: state.count - 1 })),
  reset: () => set({ count: 0 }),
}));

function Counter() {
  const { count, increment, decrement } = useCounterStore();
  return (
    <div>
      <p>{count}</p>
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
    </div>
  );
}

4. 선택적 구독

jsx
// count만 구독 — count가 바뀔 때만 리렌더링
function CountDisplay() {
  const count = useCounterStore((state) => state.count);
  return <p>{count}</p>;
}

// increment만 구독 — 절대 리렌더링 안 됨 (함수는 변하지 않음)
function IncrementButton() {
  const increment = useCounterStore((state) => state.increment);
  return <button onClick={increment}>+</button>;
}

5. slice 패턴

jsx
// store/slices/cartSlice.js
export const createCartSlice = (set, get) => ({
  cart: [],
  addToCart: (item) => set((state) => ({ cart: [...state.cart, item] })),
  removeFromCart: (id) => set((state) => ({ cart: state.cart.filter(i => i.id !== id) })),
  getTotal: () => get().cart.reduce((sum, item) => sum + item.price, 0),
});

// store/useAppStore.js
import { create } from 'zustand';
import { createCartSlice } from './slices/cartSlice';
import { createUserSlice } from './slices/userSlice';

const useAppStore = create((...args) => ({
  ...createCartSlice(...args),
  ...createUserSlice(...args),
}));

6. devtools 미들웨어

jsx
import { create } from 'zustand';
import { devtools } from 'zustand/middleware';

const useStore = create(
  devtools(
    (set) => ({
      count: 0,
      increment: () => set((s) => ({ count: s.count + 1 }), false, 'increment'),
    }),
    { name: 'MyStore' }
  )
);

Redux DevTools 확장과 연동돼 상태 변화를 시각적으로 확인.

예제 코드 / 강의 자료

전체 강의 자료와 예제 코드는 GitHub에서 자유롭게 받아볼 수 있습니다.

GitHub에서 보기 ↗