Zustand: Claude Code 활용 가이드
zustand: Claude Code 활용. 실용적인 팁과 코드 예시를 포함합니다.
Zustandでシンプルかつ強力な状態관리を実現する
Zustandは最小限のAPIで強力な状態관리を提供するReact向け라이브러리です。Redux와 같은複雑な보일러플레이트が不要で、TypeScriptとの相性も抜群です。Claude Code는 ストア설계から최적화まで的確にサポートしてくれます。
기본적인ストア설계
Claude Code에ストアの설계を依頼합시다。
> Zustandでショッピングカートのストア를 생성해줘。
> 상품추가、삭제、数量변경、合計計算を含めて。TypeScript대응で。
import { create } from "zustand";
interface CartItem {
id: string;
name: string;
price: number;
quantity: number;
}
interface CartStore {
items: CartItem[];
addItem: (item: Omit<CartItem, "quantity">) => void;
removeItem: (id: string) => void;
updateQuantity: (id: string, quantity: number) => void;
clearCart: () => void;
totalItems: () => number;
totalPrice: () => number;
}
export const useCartStore = create<CartStore>((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, quantity) =>
set((state) => ({
items: state.items.map((i) =>
i.id === id ? { ...i, quantity: Math.max(0, quantity) } : i
).filter((i) => i.quantity > 0),
})),
clearCart: () => set({ items: [] }),
totalItems: () => get().items.reduce((sum, i) => sum + i.quantity, 0),
totalPrice: () =>
get().items.reduce((sum, i) => sum + i.price * i.quantity, 0),
}));
미들웨어の활용
Zustandの미들웨어で永続化や로그출력を추가할 수 있습니다。
import { create } from "zustand";
import { persist, devtools, subscribeWithSelector } from "zustand/middleware";
import { immer } from "zustand/middleware/immer";
interface AppStore {
theme: "light" | "dark";
locale: string;
notifications: Notification[];
setTheme: (theme: "light" | "dark") => void;
setLocale: (locale: string) => void;
addNotification: (notification: Notification) => void;
removeNotification: (id: string) => void;
}
export const useAppStore = create<AppStore>()(
devtools(
persist(
immer(
subscribeWithSelector((set) => ({
theme: "light",
locale: "ja",
notifications: [],
setTheme: (theme) =>
set((state) => {
state.theme = theme;
}),
setLocale: (locale) =>
set((state) => {
state.locale = locale;
}),
addNotification: (notification) =>
set((state) => {
state.notifications.push(notification);
}),
removeNotification: (id) =>
set((state) => {
state.notifications = state.notifications.filter(
(n) => n.id !== id
);
}),
}))
),
{
name: "app-store",
partialize: (state) => ({
theme: state.theme,
locale: state.locale,
}),
}
),
{ name: "AppStore" }
)
);
スライスパターンで大規模ストアを分割
大規模애플리케이션では、ストアをスライスに分割して관리します。
// userSlice.ts
interface UserSlice {
user: User | null;
isAuthenticated: boolean;
login: (credentials: LoginCredentials) => Promise<void>;
logout: () => void;
}
const createUserSlice: StateCreator<StoreState, [], [], UserSlice> = (set) => ({
user: null,
isAuthenticated: false,
login: async (credentials) => {
const user = await authApi.login(credentials);
set({ user, isAuthenticated: true });
},
logout: () => set({ user: null, isAuthenticated: false }),
});
// uiSlice.ts
interface UISlice {
sidebarOpen: boolean;
modalStack: string[];
toggleSidebar: () => void;
openModal: (id: string) => void;
closeModal: () => void;
}
const createUISlice: StateCreator<StoreState, [], [], UISlice> = (set) => ({
sidebarOpen: true,
modalStack: [],
toggleSidebar: () => set((s) => ({ sidebarOpen: !s.sidebarOpen })),
openModal: (id) => set((s) => ({ modalStack: [...s.modalStack, id] })),
closeModal: () => set((s) => ({ modalStack: s.modalStack.slice(0, -1) })),
});
// store.ts - スライスを통합
type StoreState = UserSlice & UISlice;
export const useStore = create<StoreState>()((...a) => ({
...createUserSlice(...a),
...createUISlice(...a),
}));
セレクター에 의한성능최적화
不要な再렌더링を防ぐ위해、セレクターを使い分けます。
// 個別の値を취득(推奨)
function CartIcon() {
const totalItems = useCartStore((state) => state.totalItems());
return <span>カート ({totalItems})</span>;
}
// shallow比較で객체を취득
import { useShallow } from "zustand/react/shallow";
function CartSummary() {
const { totalItems, totalPrice } = useCartStore(
useShallow((state) => ({
totalItems: state.totalItems(),
totalPrice: state.totalPrice(),
}))
);
return (
<div>
<p>{totalItems}点の商品</p>
<p>合計: ¥{totalPrice.toLocaleString()}</p>
</div>
);
}
정리
Zustandは그シンプルさと柔軟性で、多くのReact프로젝트の状態관리に適しています。Claude Code를 활용하면 ストア설계から미들웨어구성、성능최적화まで一貫して빠르게구현할 수 있습니다。
アトミックな状態관리のアプローチはJotaiアトミック状態관리を、데이터취득との연동はTanStack Query활용가이드를 참고하세요.Zustand공식 문서도 확인해 두세요.
무료 PDF: 5분 완성 Claude Code 치트시트
이메일 주소만 등록하시면 A4 한 장짜리 치트시트 PDF를 즉시 보내드립니다.
개인정보는 엄격하게 관리하며 스팸은 보내지 않습니다.
이 글을 작성한 사람
Masa
Claude Code를 적극 활용하는 엔지니어. 10개 언어, 2,000페이지 이상의 테크 미디어 claudecode-lab.com을 운영 중.
관련 글
Claude Code 다국어 글을 매일 발행하기 전에 확인할 7가지
누락된 언어, 깨진 CTA, 반영되지 않은 배포를 막기 위해 다국어 Claude Code 글을 매일 발행하기 전에 확인할 체크리스트입니다.
Codex Automations란? 잠자는 동안 AI가 콘텐츠 운영을 처리하게 하는 방법
Codex Automations로 트래픽 분석, 주제 선정, 글 작성, CTA 개선, 배포까지 자동화하는 실전 가이드.
Claude Code × GCP Cloud Functions 완전 가이드 | 서버리스 함수 초고속 개발
Claude Code로 GCP Cloud Functions를 효율화. HTTP/Pub/Sub/Firestore 트리거 구현부터 로컬 테스트·배포 자동화까지, Masa의 실무 경험을 토대로 실제 코드로 해설.