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