728x90
728x90
Zustand
들어가며
- 전역 상태 라이브러리 중 하나인 Zustand에 대해 간단하게 정리해본다.

Zustand
개념
- 독일어로 상태(Status)라는 뜻
- 리액트 앱에서 전역 상태 관리를 해주는 아주 가볍고 단순한 라이브러리
- Redux의 복잡한 구조(Action, Reducer, Dispatch)를 사용하지 않고, Hooks 기반의 간단한 API 제공
- "minimal, fast, scalable"을 목표로 만들어졌다.
비교
Redux와 비교
- Redux는 boilerplate한 코드가 많다.
- @action@, @reducer@, @slice@를 작성해야 한다.
// Redux Toolkit
const slice = createSlice({
name: "counter",
initialState: { count: 0 },
reducers: { increment: (state) => { state.count++ } }
});
// Zustand
const useCounterStore = create((set) => ({
count: 0,
increment: () => set((s) => ({ count: s.count + 1 })),
}));
Context API와 비교
- Context API는 Provider/Consumer 패턴이 필요하며 리렌더링 문제 발생한다.
- Zustand는 구독 단위(state selector)를 지원하여 리렌더링을 최적화할 수 있다.
// Context API - 전부 리렌더링됨
const { user } = useContext(UserContext);
// Zustand - 필요한 데이터만 구독
const username = useUserStore((state) => state.user.name);
사용 방법
기본 사용 방법
import { create } from "zustand";
// 1. 상태 정의
const useCounterStore = create((set) => ({
count: 0,
increment: () => set((s) => ({ count: s.count + 1 })),
decrement: () => set((s) => ({ count: s.count - 1 })),
}));
// 2. 컴포넌트에서 사용
function Counter() {
const { count, increment, decrement } = useCounterStore();
return (
<div>
<h1>{count}</h1>
<button onClick={increment}>+1</button>
<button onClick={decrement}>-1</button>
</div>
);
}
선택적 구독 (Selector 사용)
function CountValue() {
const count = useCounterStore((state) => state.count);
return <h1>{count}</h1>;
}
function CountButtons() {
const increment = useCounterStore((state) => state.increment);
return <button onClick={increment}>+1</button>;
}
미들웨어 활용
- @persist@ : 상태를 localStorage 등에 자동 저장
- @devtools@ : Redux DevTools와 연동
import { create } from "zustand";
import { persist, devtools } from "zustand/middleware";
const useUserStore = create(
devtools(
persist(
(set) => ({
name: "guest",
setName: (name) => set({ name }),
}),
{ name: "user-storage" } // localStorage key
)
)
);
전역 스토어 분리
- 여러 개의 store를 만들어 관리 가능
- 관심사 분리 (예: @useUserStore@, @useCartStore@)
export const useUserStore = create((set) => ({
name: "",
setName: (name) => set({ name }),
}));
export const useCartStore = create((set) => ({
items: [],
addItem: (item) => set((s) => ({ items: [...s.items, item] })),
}));
비동기 로직
- @async@/@await@ 사용 가능
- API 호출 후 상태 업데이트
const useTodoStore = create((set) => ({
todos: [],
fetchTodos: async () => {
const res = await fetch("/api/todos");
const data = await res.json();
set({ todos: data });
},
}));
공식 문서
Introduction - Zustand
How to use Zustand
zustand.docs.pmnd.rs
참고 사이트
Introduction - Zustand
How to use Zustand
zustand.docs.pmnd.rs
728x90
728x90