[React] Zustand로 상태관리하기

2025. 5. 6. 22:01·JavaScript/React

Redux보다 가볍고, Context보다 편한 상태관리 솔루션

Zustand란 무엇인가?

Zustand는 독일어로 “상태(state)”라는 뜻입니다.
React에서 상태를 효율적으로 관리할 수 있도록 만든 매우 작고 단순한 상태 관리 라이브러리입니다.

  • 만든 사람: Poimandres 팀, react-three-fiber나 valtio 만든 그 팀
  • 파일 크기: 1KB 미만 (gzip)
  • 의존성: 없음, 외부 라이브러리에 전혀 의존하지 않음
  • 훅 기반 API 사용: useStore() 하나로 상태를 가져오고 업데이트까지 함

왜 Zustand를 쓰는가?

Redux보다

  • 보일러플레이트가 거의 없음
  • 리듀서, 액션, 디스패치 안 써도 됨
  • 상태 선언과 사용이 같은 파일에서 가능

Context보다

  • 불필요한 리렌더링이 없다
  • Context API는 상태 변경 시 전체 트리가 다시 렌더링됨
  • Zustand는 구독 기반으로 필요한 컴포넌트만 렌더링

MobX보다

  • 훨씬 단순하고 러닝커브 낮음
  • 단방향 흐름 유지 가능

결론:

작은 프로젝트에도 부담 없이 쓰기 좋고, 큰 프로젝트에서도 확장성 있는 상태관리 도구

Zustand의 핵심 개념

Zustand는 단 하나의 스토어를 정의하고,
훅으로 그 스토어를 구독해 상태를 읽고 변경합니다.

기억할 키워드

  • create()로 스토어 정의
  • useStore()로 상태 읽기 & 변경
  • set()으로 상태 업데이트
  • 구독 기반 상태 관리

기본 사용법

1단계: 스토어 만들기

// store.ts
import { create } from 'zustand'

type State = {
  count: number
  increase: () => void
}

export const useCounterStore = create<State>((set) => ({
  count: 0,
  increase: () => set((state) => ({ count: state.count + 1 })),
}))

2단계: 컴포넌트에서 사용

import { useCounterStore } from './store'

function Counter() {
  const count = useCounterStore((state) => state.count)
  const increase = useCounterStore((state) => state.increase)

  return (
    <div>
      <p>{count}</p>
      <button onClick={increase}>+1</button>
    </div>
  )
}

state.count만 구독하므로, 이 컴포넌트는 다른 상태가 바뀌어도 리렌더링되지 않음.

상태 구독과 성능 최적화

Zustand의 큰 장점 중 하나는 selector function을 통해
컴포넌트가 필요한 부분만 리렌더링할 수 있다는 것.

예:

const count = useCounterStore((state) => state.count)

이렇게 하면 count만 바뀔 때만 이 컴포넌트가 리렌더링됨.
불필요한 리렌더를 막는 구독 기반 최적화가 자동으로 적용됨.

비동기, persist, devtools

1. 비동기 상태 업데이트

비동기 요청 후 상태 변경도 쉽게 가능:

const useUserStore = create((set) => ({
  user: null,
  fetchUser: async () => {
    const res = await fetch('/api/user')
    const data = await res.json()
    set({ user: data })
  },
}))

2. 상태 영속화 (persist)

import { persist } from 'zustand/middleware'

const useStore = create(
  persist(
    (set) => ({
      count: 0,
      increase: () => set((state) => ({ count: state.count + 1 })),
    }),
    {
      name: 'counter-storage', // localStorage key
    }
  )
)

3. 개발자 도구 연동 (Redux DevTools)

import { devtools } from 'zustand/middleware'

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

Zustand vs Redux vs Context 비교

항목 Zustand Redux React Context
파일 수 적음 많음 적음
보일러플레이트 거의 없음 많음 없음
리렌더링 제어 O (선택적 구독) O (useSelector) X (전부 리렌더)
러닝커브 낮음 높음 낮음
사용 목적 전역 상태 복잡한 상태 흐름 간단한 전역 상태
미들웨어 지원 있음 있음 없음

 

언제 Zustand를 선택할까?

Zustand는 다음과 같은 상황에서 훌륭한 선택이 됩니다.

  • Context로는 리렌더링 최적화가 어렵고 Redux는 너무 무겁게 느껴질 때
  • 전역 상태가 필요하지만 복잡한 구조는 피하고 싶을 때
  • 상태 관리 도구를 빠르게 도입하고 싶을 때

규모가 작아도, 클라이언트 상태를 깔끔하게 유지하고 싶다면
Zustand는 개발자에게 “귀찮음 없는 상태관리”를 선물합니다.

728x90
'JavaScript/React' 카테고리의 다른 글
  • [React] Code Splitting (코드 스플리팅)
  • [React] Lazy Loading (지연 로딩)
  • [React] Props 지옥에서 벗어나는 법
  • [React] Context API
츄핑
츄핑
    250x250
  • 츄핑
    개발로그
    츄핑
  • 전체
    오늘
    어제
    • 분류 전체보기
      • CS
        • 자료구조
        • 알고리즘
        • 운영체제
        • 네트워크
        • 데이터베이스
        • 인프라
        • Web
      • PS
        • 백준
      • JavaScript
        • React
        • Express
        • NestJS
        • TypeScript
        • Node.js
        • Electron
      • Java
        • Spring
      • Dart
        • Flutter
      • PHP
        • CodeIgniter
      • etc
        • 이산수학
        • 선형대수학
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    티스토리챌린지
    오블완
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
츄핑
[React] Zustand로 상태관리하기
상단으로

티스토리툴바