react-state について
react-state は、React アプリに Zustand v5 の状態管理を導入するためのスキルです。型安全なストア、セレクターのパフォーマンス、ミドルウェア構成、ドメイン別の整理を扱い、サーバー状態には TanStack Query を推奨します。
主な機能
- 01Zustand v5 の TypeScript ストアパターン
- 02セレクターと useShallow の使い方
- 03devtools、persist、immer の構成
- 04ドメイン別のストア整理
- 05v4 移行とアンチパターンのガイド
活用シーン
- 01React アプリに共有状態を追加
- 02auth、cart、UI のストアを整理
- 03トークンを除いた状態の永続化
- 04Zustand v4 のストアコードを移行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ fusengine/ agents --skill react-stateインストール後、Claude Code で/react-stateを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/auto-selectors.mdinstallation.mdmiddleware.mdmigration-v5.mdreset-state.mdslices.mdstore-patterns.mdsubscribe-api.mdtesting.mdtypescript.md詳細
1 つの巨大なストアではなく、ドメインごとにストア(auth、cart、ui、theme)を分ける方法、SOLID に沿ったファイル構成(store.ts、store.interface.ts、use-store.ts)、および禁止パターン(auth トークンの永続化、v4 構文、useShallow の省略)について説明します。これは Zustand のプレーンな React 版です(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() を使用したストアの作成 | 50 |
store.interface.ts | TypeScript のインターフェース | 30 |
use-store.ts | セレクターを使用するカスタムフック | 20 |
主な概念
ストアの作成(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つ用意します(auth、cart、ui、theme)
- サーバーデータは別の場所で管理 - サーバー状態には TanStack Query を使用します
- 開発時のみ DevTools を使用 - process.env のチェックで DevTools をラップします
- persist の partialize - 必要なフィールドだけを永続化し、トークンは絶対に永続化しません
禁止されているパターン
| パターン | 理由 | 代替案 |
|---|---|---|
| 認証トークンの永続化 | セキュリティ上の脆弱性 | httpOnly クッキー |
| オブジェクトに useShallow を使用しない | 過剰な再レンダリング | useShallow(selector) |
| v4 の構文 | TypeScript の型推論が機能しない | v5 のカリー化 create<T>()() |
| 巨大なモノリシックストア | 保守が困難 | スライスまたはストアの分割 |