現在のプロジェクトでは、グローバルな状態管理に SWR が中心的に利用されています。特に useSWRStatic や useContextSWR といったカスタムフックを用いて、クライアントサイドの状態管理も行われています。
しかし、以下の課題が認識されています。
useSWRStatic 周りで、意図しない挙動やデータの不整合が発生している可能性が指摘されています。カスタムフックの複雑さやキャッシュの扱い方が原因である可能性があります。これらの課題を解決し、より堅牢でメンテナンスしやすく、パフォーマンスの良い状態管理を実現することを目的とします。
SWR と、クライアントサイド状態管理に特化した軽量ライブラリ(Jotai)を併用する方針を採用します。
Jotai: クライアントサイドで完結するUI状態や、同期的な状態管理を担当します。(例: モーダルの開閉、テーマ設定、フォーム入力値など)
graph TD
subgraph "提案: 役割分担"
A[React Component] --> B{useSWR};
B --> C[SWR Cache (サーバーキャッシュ)];
C -- データフェッチ --> D[API Server];
A --> E{useAtom (Jotai)};
E --> F[Jotai Atoms (クライアント状態)];
end
この方針により、以下のメリットが期待されます。
useSWRStatic, useContextSWR) が不要になる可能性があります。以下のステップで段階的に改善を進めます。
クライアントサイド状態管理ライブラリとして Jotai を導入し、その使用感やプロジェクトへの適合性を確認するため、小規模な PoC を実施します。
useSWRStatic や useContextSWR で管理されているクライアント状態の中から、比較的シンプルで影響範囲の小さいものをいくつか選定します。(例: isDrawerOpened, sidebarContents, preferCollapsedMode など)PoC の結果を踏まえ、Jotai を本格的に導入し、既存の状態管理を段階的に移行します。
useSWRStatic / useContextSWR を利用している箇所を特定し、クライアント状態管理の部分を新しいライブラリに置き換えていきます。
useSWRStatic, useContextSWR) の利用箇所を徐々に減らしていきます。useSWRStatic などに起因する可能性のあったバグが解消される。以下の状態を Jotai に移行完了しました:
PoC フェーズ:
useDrawerOpened: サイドバーのドロワー表示状態usePreferCollapsedMode: サイドバーの折りたたみモード設定(永続化含む)追加移行完了:
useSidebarMode: サイドバーの表示モード管理(DRAWER, COLLAPSED, DOCK)
editorMode と isDeviceLargerThanXl の状態との連携PagePathNavSticky, Sidebar, SidebarContents, PrimaryItems)移行を通じて、以下のパターンが確立されました:
states/ ディレクトリに配置useSidebarMode)の実装パターン以下の状態を Jotai を使用して実装し、検証を行いました:
useDrawerOpened: サイドバーのドロワー表示状態usePreferCollapsedMode: サイドバーの折りたたみモード設定(ユーザー設定の永続化を含む)useSidebarMode: サイドバーの表示モード管理(複数の状態を組み合わせた派生状態)useDeviceLargerThanXl: デバイスサイズ判定states/ ディレクトリ構造を作成し、責務別に分割:
states/ui/sidebar.ts: サイドバー関連の状態定義・操作states/ui/device.ts: デバイス状態states/ui/editor.ts: エディター関連の状態states/ui/helper.ts: 型定義ヘルパーstates/hydrate/sidebar.ts: サイドバー状態のSSRハイドレーション専用DrawerTogglerGrowiNavbarBottomEditorNavbarBottomSidebarToggleCollapseButtonPagePathNavStickySidebarContentsPrimaryItemspages/utils/commons.ts の初期化処理を更新useState に近く、理解しやすい実装となりました。PoC の成功を受けて、以下の段階的な移行を実施します:
useCurrentSidebarContents: サイドバーのコンテンツタイプ(永続化必要)useCollapsedContentsOpened: 折りたたまれたコンテンツの開閉状態useCurrentProductNavWidth: プロダクトナビゲーションの幅(永続化必要)usePageControlsX: ページコントロールのX座標useSelectedGrant: 選択された権限設定stores/modal.tsx の内容)states/ui/ 配下に機能別でファイルを分割{feature}Atom および use{Feature} パターンを継続scheduleToPut を使用した永続化を実装UseAtom ヘルパー型を使用詳細な移行計画とTODOリストは jotai-migration-todo.md を参照してください。