stack-analysis
CHAPTER 6 / 90
읽기 약 2분
FUNCTION
상태 관리 비교: useState vs Zustand vs Redux
핵심 개념
로컬 vs 글로벌 판단·Zustand 패턴·Redux Toolkit·Jotai/Recoil — 이커머스 장바구니.
본문
상태 관리 결정 트리
상태가 컴포넌트 1개에서만 사용?
├─ Yes → useState
└─ No (여러 컴포넌트 공유)
├─ 부모-자식 관계 단순?
│ ├─ Yes → props drilling 또는 context
│ └─ No
│ ├─ 작은 앱 + 단순 상태 → Zustand
│ ├─ 큰 앱 + 복잡 상태 → Redux Toolkit
│ └─ Atomic 모델 선호 → JotaiZustand — 가장 단순한 글로벌 상태
// store/cart.ts
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
type CartItem = { id: string; name: string; price: number; quantity: number };
type CartStore = {
items: CartItem[];
addItem: (item: Omit<CartItem, 'quantity'>) => void;
removeItem: (id: string) => void;
updateQuantity: (id: string, qty: number) => void;
total: () => number;
clear: () => void;
};
export const useCartStore = create<CartStore>()(
persist(
(set, get) => ({
items: [],
addItem: (item) => set((state) => {
const existing = state.items.find(i => i.id === item.id);
if (existing) {
return {
items: state.items.map(i =>
i.id === item.id ? { ...i, quantity: i.quantity + 1 } : i
),
};
}
return { items: [...state.items, { ...item, quantity: 1 }] };
}),
removeItem: (id) => set((state) => ({
items: state.items.filter(i => i.id !== id),
})),
updateQuantity: (id, qty) => set((state) => ({
items: state.items.map(i => i.id === id ? { ...i, quantity: qty } : i),
})),
total: () => get().items.reduce((sum, i) => sum + i.price * i.quantity, 0),
clear: () => set({ items: [] }),
}),
{ name: 'cart-storage' } // localStorage
)
);
// 사용
function CartIcon() {
const itemCount = useCartStore((state) => state.items.length);
return <div>장바구니: {itemCount}</div>;
}
function CartPage() {
const { items, removeItem, total } = useCartStore();
return (
<div>
{items.map(item => (
<div key={item.id}>
{item.name} x {item.quantity}
<button onClick={() => removeItem(item.id)}>제거</button>
</div>
))}
<div>총: {total()}원</div>
</div>
);
}Redux Toolkit — 큰 앱
// store/cartSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
const cartSlice = createSlice({
name: 'cart',
initialState: { items: [] as CartItem[] },
reducers: {
addItem: (state, action: PayloadAction<Omit<CartItem, 'quantity'>>) => {
const existing = state.items.find(i => i.id === action.payload.id);
if (existing) {
existing.quantity += 1;
} else {
state.items.push({ ...action.payload, quantity: 1 });
}
},
removeItem: (state, action: PayloadAction<string>) => {
state.items = state.items.filter(i => i.id !== action.payload);
},
},
});
export const { addItem, removeItem } = cartSlice.actions;
export default cartSlice.reducer;
// store/index.ts
import { configureStore } from '@reduxjs/toolkit';
import cartReducer from './cartSlice';
export const store = configureStore({
reducer: { cart: cartReducer },
});
// 사용
import { useDispatch, useSelector } from 'react-redux';
function CartIcon() {
const items = useSelector((state: RootState) => state.cart.items);
return <div>장바구니: {items.length}</div>;
}Jotai — Atomic
// atoms.ts
import { atom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
export const itemsAtom = atomWithStorage<CartItem[]>('cart', []);
export const totalAtom = atom((get) =>
get(itemsAtom).reduce((sum, i) => sum + i.price * i.quantity, 0)
);
// 사용
import { useAtom, useAtomValue } from 'jotai';
function Cart() {
const [items, setItems] = useAtom(itemsAtom);
const total = useAtomValue(totalAtom);
// ...
}비교
| 라이브러리 | 번들 크기 | 학습 곡선 | 적합 |
|---|---|---|---|
| useState | 0 | ⭐ | 컴포넌트 로컬 |
| Context | 0 | ⭐⭐ | 작은 앱 + 단순 |
| Zustand | 1KB | ⭐⭐ | 중규모 + 단순 |
| Jotai | 3KB | ⭐⭐⭐ | atomic 선호 |
| Redux Toolkit | 14KB | ⭐⭐⭐⭐ | 대규모 + 복잡 |다음 챕터
CH.7 "데이터 페칭: TanStack Query" — 서버 상태 관리.
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 코드의 상태 관리 부분을 분석해서 실전 분석 + 개선 우선순위를 알려줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
상태 관리 관련 인기 라이브러리/패턴 5개를 비교 분석해서 패턴 추출를 알려줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 프로젝트 전체에서 상태 관리 최적화 가능 위치를 보고해줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 한국 프론트엔드 시장의 상태 관리 트렌드를 솔직히 알려줘.
⭐ 이것만 기억하세요
상태 관리 비교: useState vs Zustand vs Redux는 이 3가지만 확실히 잡으세요
1.Zustand는 가장 단순 + 작은 번들 — 80% 케이스에 충분
2.Redux Toolkit은 큰 팀 + 복잡한 상태 — 학습 곡선 높지만 도구 풍부
3.다음 챕터 CH.7에서 TanStack Query — 서버 상태는 클라이언트 상태와 별개
공유하기
진행도 6 / 90