frontend-review-state について
フロントエンドチームが状態管理ライブラリの使い方を評価するための、アーキテクチャレビュー手順を提供するスキルです。状態の分類ミスやグローバル状態のアンチパターン、ログアウト後のキャッシュ消去漏れを調べ、報告書を作成します。
主な機能
- 01状態管理ライブラリと利用状況の把握
- 02サーバー・URL・フォーム状態の分類確認
- 03Jotai、Zustand、Redux、Context のレビュー
- 04ログアウト時のキャッシュと状態消去確認
- 05ファイルと行番号付き報告書の作成
活用シーン
- 01グローバル状態に誤って置かれたサーバーデータの特定
- 02大きな atom・store や粗い購読のレビュー
- 03ログアウト後のキャッシュ無効化の確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mizchi/ skills --skill frontend-review-stateインストール後、Claude Code で/frontend-review-stateを入力して読み込まれたか確認します。
同梱ファイルREADME.md
詳細
フロントエンドレビュー — 状態管理
フロントエンドプロジェクトの状態管理アーキテクチャをレビューします。AI が生成する問題で最もよく見られるのは、すべてをグローバル状態に入れること、TanStack Query ではなくサーバーデータをグローバルストアに保存すること、そして粒度の粗いセレクターを使ってコンポーネントツリー全体を再レンダリングさせることです。
手順
package.jsonを読み、使用されている状態管理ライブラリを特定します。- グローバル状態の使用パターンを grep で検索します。
# Jotai grep -rn "atom\|useAtom\|useAtomValue" src/ --include='*.ts' --include='*.tsx' | wc -l # Zustand grep -rn "create\b\|useStore\b" src/ --include='*.ts' --include='*.tsx' | head -20 # Redux grep -rn "createSlice\|useSelector\|useDispatch" src/ --include='*.ts' --include='*.tsx' | head -20 # Context grep -rn "createContext\|useContext" src/ --include='*.ts' --include='*.tsx' | head -20 - 最も大きな atom / store 定義から 3~5 個を抜き出し、何が格納されているかを確認します。
- グローバルストアに保存されたサーバー状態がないか確認します(代わりに TanStack Query / SWR を使うべきです)。
- グローバルストアに保存された URL 状態がないか確認します(代わりに
useSearchParams/nuqsを使うべきです)。 - グローバルストアに保存されたフォーム状態がないか確認します(代わりに React Hook Form を使うべきです)。
状態の分類
状態を種類ごとに正しく分類します。各種類には専用のツールがあり、間違ったツールを使うことが、状態管理のバグのほとんどの根本原因です。
Server state → TanStack Query / SWR (not global store)
URL state → useSearchParams / nuqs (not global store)
Form state → React Hook Form (not global store)
UI local → useState / useReducer (component-scoped)
UI global → Jotai / Zustand / Context (minimum scope)
グローバルな Jotai/Zustand/Redux ストア内で見つかったサーバー状態、URL 状態、フォーム状態にはフラグを付けます。これらは常にバグか設計上の誤りです。
ライブラリ固有の確認事項
Jotai
- atom の粒度:論理的な単位ごとに atom を 1 つ使います。大きなオブジェクト atom(
{ user, theme, notifications, ... })は使いません。 - 派生状態:計算済みの値を保存する代わりに、計算値には
atom(get => ...)を使います。 - 副作用:
atomの setter コールバック内ではなく、atomEffect/useAtomEffectに分離します。 - テスト容易性:モジュールのトップレベルで宣言された atom はグローバルなシングルトンになります。テスト / Storybook では
Providerのスコープを使います。
// Bad: monolithic atom
const appStateAtom = atom({ user: null, theme: 'light', selectedItems: [], filterQuery: '' });
// Good: split + derived
const userAtom = atom<User | null>(null);
const themeAtom = atom<'light' | 'dark'>('light');
const filteredItemsAtom = atom((get) =>
get(allItemsAtom).filter(item => item.name.includes(get(filterQueryAtom)))
);
Zustand
- セレクターの使用:
useStore(state => state.specificField)を使います。ストアオブジェクト全体を購読することは避けてください。 - 浅い比較:複数のフィールドをオブジェクトとして選択する場合は、
zustand/shallowのshallowを使います。 - 直接変更しない:常に
set/getを使い、Zustand の setter の外で状態を変更してはいけません。
// Bad: subscribes to everything
const { user, theme, cart } = useStore();
// Good: selector per field (or shallow for multi-field)
const user = useStore(state => state.user);
const { theme, cart } = useStore(useShallow(state => ({ theme: state.theme, cart: state.cart })));
Redux Toolkit
- 手書きの reducer ではなく、
createSliceを使っていますか? - 非同期データの取得には、手動の
dispatchチェーンではなくcreateAsyncThunkまたは RTK Query を使っていますか? - サーバー状態は slice ではなく、RTK Query / TanStack Query にありますか?
Context API
- Context の値が変わると、すべての Consumer が再レンダリングされます。Context の値がオブジェクトの場合は、論理的なグループごとに別々の Context(例:
AuthContext、ThemeContext)に分けます。 - Context は、変化の頻度が低く安定した値(認証ユーザー、テーマ、i18n ロケール)に適しています。
- 更新頻度の高い値を管理する汎用の状態管理手段として Context を使わないでください。
ログアウトとキャッシュの無効化
よくあるバグとして、ログアウト後に次のユーザーがログインすると、前のセッションのキャッシュデータが表示されることがあります。
ログアウトハンドラーで次のことが行われているか確認します。
- サーバーのログアウトエンドポイントを呼び出す(セッションを失効させる)
- TanStack Query / SWR のキャッシュをクリアする(
queryClient.clear()) - 認証に関連するすべてのグローバル atom / Zustand ストアをリセットする
/loginに移動する(クリア後に行い、クリア前には行わない)
出力
<client-repo>/.frontend-review/report/latest/md/state-review.md に次の内容を記述します。
- 状態の一覧:使用されているライブラリ、atom/store/context のおおよその数
- 誤分類された状態:グローバルストア内で見つかったサーバー状態 / URL 状態 / フォーム状態(これらはバグです)
- 見つかったアンチパターン:ファイル名と行番号を記載
- ログアウト / キャッシュの不備:見つかった場合
- 推奨する PR:それぞれ 1 つの論理的なリファクタリングに範囲を限定
200 行以内に収めます。ファイル単位の詳細はレポートではなく、生の検索結果に記載します。
範囲
- 状態管理コードを書き換えてはいけません。レポートでは不備を特定し、修正はエンジニアが実施します。
- クライアントリポジトリ内のソースファイルに手を加えてはいけません。
- レンダリングパフォーマンス(再レンダリング、memo の使用状況)は
frontend-review-performanceで扱います。
参考資料
- チェックリスト:
23-state-management.md、17-pure-io-separation.md、21-api-layer.md - 関連項目:
frontend-review-performance(再レンダリングのプロファイリング)
コメント
Markdown 対応