react-state について
React アプリで Zustand v5 によるグローバル状態管理を実装するためのスキルです。共有クライアント状態を整理する開発者向けに、型安全なストア作成、セレクター、中間ウェアの構成を扱います。
主な機能
- 01Zustand v5 のカリー化ストア作成
- 02セレクターによる状態アクセス
- 03配列・オブジェクト用 useShallow
- 04devtools、persist、immer の合成
- 05ドメイン別のストア構成
- 06TypeScript を意識したファイル構成
活用シーン
- 01React コンポーネント間の共有状態設定
- 02認証、カート、UI、テーマのストア整理
- 03配列・オブジェクトセレクターによる再描画の削減
- 04TypeScript での中間ウェア構成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ fusengine/ claude-plugins --skill react-stateインストール後、Claude Code で/react-stateを入力して読み込まれたか確認します。
詳細
巨大なストアを1つ作るのではなく、ドメインごと(auth、cart、ui、theme)にストアを分割する方法、SOLID に基づくファイル構成(store.ts、store.interface.ts、use-store.ts)、および禁止パターン(auth トークンの永続化、v4 構文の使用、useShallow の不使用)を扱います。これはプレーンな React 向けの Zustand です(App Router のリクエスト分離に関する考慮事項はありません)。Next.js App Router については nextjs-zustand を、サーバー状態の管理にはこのスキルではなく TanStack Query を使用してください。
React 向け Zustand
React 18 以降の useSyncExternalStore を使用する、最小限でスケーラブルな状態管理です。
エージェントのワークフロー(必須)
実装の前に必ず、次の3つのエージェントを並行して起動してください。それぞれ name を指定して Agent を1回呼び出します。
- fuse-ai-pilot:explore-codebase - 既存のストアと状態管理パターンを分析します
- fuse-ai-pilot:research-expert - Context7/Exa を使用して、最新の Zustand v5 ドキュメントを確認します
- mcp__context7__query-docs - ミドルウェアと TypeScript のパターンを確認します
実装後、検証のために fuse-ai-pilot:sniper を実行してください。
概要
使用する場面
- React アプリケーションでグローバル状態を管理する場合
- コンポーネント間で共有する状態が必要な場合
- 状態を localStorage/sessionStorage に永続化する場合
- UI の状態(モーダル、サイドバー、テーマ、カート)を構築する場合
- 複雑な状態管理で React Context を置き換える場合
Zustand v5 を選ぶ理由
| 特徴 | メリット |
|---|---|
| 最小限の API | シンプルな create() 関数で、ボイラープレートが不要です |
| React 18 ネイティブ | useSyncExternalStore を使用し、シムは不要です |
| TypeScript を優先 | カリー化パターンにより、完全な型推論が得られます |
| ミドルウェアスタック | devtools、persist、immer を組み合わせられます |
| バンドルサイズ | gzip 圧縮後で約2KB。最小の状態管理ライブラリです |
| プロバイダー不要 | Context のラッパーなしで、ストアに直接アクセスできます |
重要なルール
- 配列/オブジェクトには useShallow を使用 - 不要な再レンダリングを防ぎます
- v5 のカリー化構文 -
create<State>()((set) => ({...})) - SOLID に沿ったパス - ストアは
modules/[feature]/src/stores/に配置します - ストアを分割 - ドメインごとに1つのストアを作成します(auth、cart、ui、theme)
- サーバー状態は別の手段で管理 - サーバー状態には TanStack Query を使用します
SOLID アーキテクチャ
モジュール構成
機能モジュールごとにストアを整理します。
modules/cores/stores/- 共有ストア(theme、ui)modules/auth/src/stores/- 認証状態modules/cart/src/stores/- カートの状態modules/[feature]/src/interfaces/- ストアの型
ファイル構成
| ファイル | 目的 |
|---|---|
store.ts | create() を使用したストアの作成(最大40行、owner ルール) |
store.interface.ts | TypeScript インターフェース |
use-store.ts | セレクターを備えたカスタムフック |
主な概念
ストアの作成(v5 構文)
TypeScript の型推論には二重の括弧が必要です。カリー化パターンにより、完全な型安全性が得られます。
ミドルウェアの合成
ミドルウェアを devtools -> persist -> immer の順に重ねます。順序は TypeScript の型に影響します。
セレクターパターン
パフォーマンスのため、常に useStore((s) => s.field) を使用してください。配列/オブジェクトのセレクターには useShallow を使用します。
リファレンスガイド
| 必要な情報 | リファレンス |
|---|---|
| 初期設定 | installation.md |
| ストアのパターン | store-patterns.md |
| ミドルウェア | middleware.md |
| TypeScript | typescript.md |
| スライスパターン | slices.md |
| 自動セレクター | auto-selectors.md |
| 状態のリセット | reset-state.md |
| Subscribe API | subscribe-api.md |
| テスト | testing.md |
| v4 から v5 への移行 | migration-v5.md |
ベストプラクティス
- セレクターパターン - パフォーマンスを向上させるため、常に
useStore((s) => s.field)を使用します - useShallow - 配列やオブジェクトのセレクターをラップして、再レンダリングを防ぎます
- ストアを分ける - ドメインごとに1つのストアを使用します(認証、カート、UI、テーマ)
- サーバーデータは別の場所で管理する - サーバー状態には TanStack Query を使用します
- 開発時のみDevToolsを使用する - DevToolsを process.env のチェックでラップします
- persistを部分適用する - 必要なフィールドのみを永続化し、トークンは決して永続化しません
禁止されているパターン
| パターン | 理由 | 代替案 |
|---|---|---|
| 認証トークンの永続化 | セキュリティ上の脆弱性 | httpOnly Cookie |
| オブジェクトにuseShallowを使わない | 過剰な再レンダリング | useShallow(selector) |
| v4構文 | TypeScriptの型推論が機能しない | v5のカリー化 create<T>()() |
| 巨大なモノリシックストア | 保守が難しい | スライスまたは個別のストア |