mcpField
Z
zustand

zustand

github.com/pedronauck開発647354 回インストール1 日前に更新
リポジトリ

zustand について

プロジェクトでZustandを使う開発者向けの状態管理ガイドです。ドメイン別ストア、型付きセレクター、ミドルウェアを扱い、共有クライアント状態とサーバー状態を区別します。

主な機能

  1. 01ドメイン別ストア設計
  2. 02TypeScriptによる型安全性
  3. 03大規模ストア向けスライスパターン
  4. 04購読を絞るセレクターフック
  5. 05永続化とImmerミドルウェア

活用シーン

  1. 01新機能のストア設計
  2. 02大規模ストアのスライス分割
  3. 03必要な状態だけを購読
  4. 04永続化する状態の選定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/pedronauck/skills --skill zustand

インストール後、Claude Code で/zustandを入力して読み込まれたか確認します。

同梱ファイルreferences/patterns.md

詳細

Zustand の状態管理ガイド

このスキルでは、このプロジェクトで Zustand を使用するためのガイドライン、パターン、ベストプラクティスを紹介します。

クイックスタート

ストアの詳細なパターン、ミドルウェアの使用方法、包括的な例については、references/patterns.md を参照してください。

基本理念

  • 共有クライアント状態のみ:Zustand は共有クライアント状態に使用し、サーバー状態には使用しないでください(サーバー状態には TanStack Query を使用してください)。
  • ドメイン固有のストア:ストアは特定のドメインに特化させてください。
  • 型安全性:TypeScript を活用して、ストアに完全な型を付けてください。
  • シンプルさ:複雑な抽象化よりもシンプルさを優先してください。

ストアの構成

必須パターン
  • ドメインごとに個別のストアを作成する
  • 大規模なストアにはスライスパターンを使用する
  • ストアは、それを使用する機能の近くに配置する
  • DX とパフォーマンスを向上させるため、型付きセレクターフックをエクスポートする
推奨ミドルウェア構成

本番用ストアでは、次のミドルウェアを組み合わせて使用してください。

import { create } from "zustand";
import { devtools, persist } from "zustand/middleware";
import { immer } from "zustand/middleware/immer";

export const useExampleStore = create<ExampleState>()(
  devtools(
    persist(
      immer((set, get) => ({
        // state and actions
      })),
      { name: "example-storage" }
    ),
    { name: "example-store" }
  )
);
ストア構造のテンプレート
interface StoreState {
  // State properties
  data: DataType | null;
  isLoading: boolean;
  // Group actions together
  actions: {
    fetchData: () => Promise<void>;
    updateData: (updates: Partial<DataType>) => void;
    reset: () => void;
  };
}
セレクターフックのパターン

パフォーマンスを最適化するため、必ずセレクターフックを作成してください。

// Bad - subscribes to entire store
const { user, isLoading } = useAuthStore();

// Good - subscribes only to specific slices
export const useUser = () => useAuthStore((state) => state.user);
export const useIsLoading = () => useAuthStore((state) => state.isLoading);
export const useAuthActions = () => useAuthStore((state) => state.actions);

ベストプラクティス

  1. ストアは特定のドメインに特化させる
  2. TypeScript を使用して、完全な型安全性を確保する
  3. ミドルウェアを活用して、一般的なパターンに対応する(devtools、persist、immer)
  4. パフォーマンス向上のためにセレクターフックを作成する
  5. 複雑なネスト状態の更新には immer を使用する
  6. 必要な状態のみを永続化する — partialize オプションを使用する
  7. ストアを十分にテストする
  8. ローディング状態とエラー状態を使って、非同期処理を適切に扱う
  9. 適切な場合は楽観的更新を実装する
  10. ストアの構造とアクションを文書化する

よくあるタスク

新しいストアの作成
  1. 型付きアクションを含む状態インターフェースを定義する
  2. 適切なミドルウェアを使ってストアを作成する
  3. 状態の各スライスに対応するセレクターフックをエクスポートする
  4. 機能のバレルエクスポートに追加する
状態の永続化

必要なデータのみを永続化するには、partialize とともに persist ミドルウェアを使用してください。

persist(
  (set) => ({ /* ... */ }),
  {
    name: "store-key",
    partialize: (state) => ({
      // Only persist these fields
      user: state.user,
      preferences: state.preferences,
    }),
  }
);
更新への Immer の使用

Immer を使用すると、変更可能な形式で更新を記述しながら、不変の状態を生成できます。

immer((set) => ({
  updateNested: (id, value) => {
    set((state) => {
      const item = state.items.find((i) => i.id === id);
      if (item) {
        item.value = value; // Mutable style, but produces immutable state
      }
    });
  },
}));

検証チェックリスト

Zustand に関するタスクを完了する前に、次の項目を確認してください。

  • ストアがドメイン固有で、特定の領域に特化している
  • TypeScript インターフェースが適切に定義されている
  • ミドルウェアが正しい順序で適用されている(devtools > persist > immer)
  • パフォーマンス向上のためのセレクターフックが作成されている
  • アクションが actions オブジェクトにまとめられている
  • 必要な状態のみが永続化されている
  • 型チェック(pnpm run typecheck)とテスト(pnpm run test)を実行する

詳細なルール、例、アンチパターンについては、references/patterns.md を参照してください。

コメント