Build

Zustand Playground

Zustand、React Hook Form、Zod、store間同期をブラウザで試すための外部Playground。

zustandreact-hook-formzodplaygroundexternal-demo

これは何か

TOOLS BOX 本体に組み込んだ画面ではありません。別リポジトリで動かす外部 Playground です。

Zustand・React Hook Form・Zod の組み合わせを実際に触って理解するための実験場です。壊して試すための環境として、TOOLS BOX 本体とは意図的に分けています。

GitHub リポジトリは現在準備中(private)です。動作確認は外部デモから行えます。

何を学べるか

この Playground では以下を動作確認できます。

  • create で store を定義する
  • selector による購読で再レンダリングを最小化する
  • set / get で状態を更新・参照する
  • getState() と subscribe の違いを確かめる
  • subscribe / subscribeWithSelector で外部変更を検知する
  • unsubscribe で購読を解除・管理する
  • devtools middleware で Redux DevTools と連携する
  • 各 store を初期値に リセット して挙動を再現する
  • Zod schema・バリデーション・coerce で入力を正規化する
  • React Hook Form の watch で入力をリアルタイムに store へ反映する
  • storeSync で複数 store 間の状態を自動同期する
  • selector で取り出した action を コンポーネント間で受け渡す

画面構成

┌──────────────────────────────────┬─────────────────┐
│  タブ切り替えエリア               │  Store Monitor  │
│  ┌────────────────────────────┐  │  (常時表示)   │
│  │ フォーム / 詳細 / 結果表示  │  │                 │
│  └────────────────────────────┘  │  settingsStore  │
│                                  │  profileStore   │
│  [全ストアをリセット]            │  uiStore        │
│                                  │  detailStore    │
└──────────────────────────────────┴─────────────────┘
タブ内容
フォーム設定入力。入力と同時にストアへリアルタイム反映
詳細mode / 推奨レートの操作。別ストアへの書き戻し例
結果表示全ストアの確定値をまとめて表示
Store Monitor右サイドに常時表示。全ストアをリアルタイム監視

ストア構成

store役割
settingsStoreフォーム入力値(Zod 正規化済み)を保持。同期の起点
profileStore表示用に整形したプロフィール値(settingsStore から同期)
detailStore詳細画面用の派生状態(suggestedRate など)
uiStoreアクティブなタブ(表示制御のみ)

データの流れ

フォーム入力(キー入力)
  ↓
React Hook Form (watch) でリアルタイム検知
  ↓
patchFormData で settingsStore を即時更新
  ↓
storeSync (subscribe) が変更を検知
  ↓
profileStore / detailStore へ自動同期
  ↓
selector で各 UI を再描画
  ↓
保存ボタン押下時: Zod parse → setFormData で確定値を保存

Zustand API の使い分け

場所使うもの目的
Store 内部set, get状態更新・現在値参照
React componentuseStore(selector)値の購読・再描画
React 外store.getState()現在値取得(再描画なし)
store 同期層subscribe()変更監視
終了処理unsubscribe()購読解除

注意点

  • getState() は現在値を読むだけで React の再描画を発生させません。UI で値を表示する場合は selector を使います
  • patchFormData は Zod を通らないため、呼び出し側で値の正規化・クランプが必要です
  • subscribeWithSelector の shallow 比較により、関係ないフィールドの変更では同期が走りません

触り方

リポジトリをクローンしてローカルで起動できます。

GitHub で見る

npm install
npm run dev

起動後、以下の URL でデモ画面が開きます。

http://localhost:3000/zustand-demo

TOOLS BOX 本体と分ける理由

Playground は壊して試す場所です。TOOLS BOX 本体は整理された教材・完成例の場所です。

zustand_test は Next.js・React・MUI のバージョン構成が TOOLS BOX 本体とは異なります。そのまま取り込むと依存関係や UI 方針が重くなるため、現時点では外部 Demo として分けて運用します。

将来的な組み込み案

フェーズ内容
Phase A外部 Demo Build として掲載(現在の状態)
Phase BVercel 等にデプロイし、外部デモ URL を設定する
Phase CTOOLS BOX 本体に Tailwind UI として /playgrounds/zustand-demo を移植する
Phase DZustand Playground の作り方を Playbook として整理する(完了)

関連 Playbook

外部デモを見る →Private Repo