概要
状態(state)とは、UIやアプリケーションが“今どうあるか”を定義する情報の集合体である。
状態管理とは、**「状態をどこに持ち」「どう変化させ」「どう再現性を担保するか」**を設計する行為である。
本稿では、以下を軸に状態管理を構造的に整理する:
- ローカルステート vs グローバルステートの役割と境界
- 状態の責務とスコープの設計
- ステートマシンによる状態遷移の明示化
- 状態変更のトリガーと影響範囲の制御
- 現場における実用アプローチの選定基準
1. ローカルステート:コンポーネント内の状態
let count = 0;
function increment() {
count++;
render(count);
}
- ✅ コンポーネント内完結
- ✅ UIに直接関係する短命ステート向き
- ❌ 複数コンポーネントで共有すると破綻
2. グローバルステート:アプリケーション全体で共有される状態
const appState = {
user: null,
theme: 'dark',
isLoading: false
};
- ✅ 認証情報・設定・ネットワーク状態など
- ✅ 単一の“真実の情報源”(Single Source of Truth)
- ❌ 不用意に増やすと依存爆発
3. ステートマシン的思考:状態遷移を制御する
✅ 明示的な“状態 → 状態”の遷移モデル
const state = {
status: 'idle', // idle → loading → success / error
};
function transition(event) {
if (state.status === 'idle' && event === 'FETCH') {
state.status = 'loading';
} else if (state.status === 'loading' && event === 'SUCCESS') {
state.status = 'success';
}
}
→ ✅ 状態とイベントの“許容遷移”を明文化
→ ✅ 誰がいつ何を変えるかが見える設計に
4. 状態を「責務」で分類する戦略
状態の種類 | 例 | 保持場所 |
---|---|---|
表示用の一時状態 | モーダル開閉・フォームの入力内容 | ローカルステート |
アプリケーション状態 | 認証ユーザ・テーマ・カート | グローバルステート |
ネットワーク状態 | isLoading, errorMessage | 一時的にはローカル、共有が必要ならグローバル |
状態遷移 | 認証: 未ログイン → ログイン中 → 完了 | ステートマシンモデル |
5. グローバルステートを管理する手段
✅ Context API(Reactなど)
const ThemeContext = createContext('dark');
- ✅ 軽量で構成もシンプル
- ❌ 状態の更新頻度が高いと再レンダリング地獄
✅ 状態管理ライブラリ(Zustand, Redux, Vuex など)
const useStore = create(() => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 }))
}));
- ✅ スコープを切ってセレクティブ購読
- ✅ ミドルウェアによるログ・永続化も可
- ❌ 抽象化しすぎると複雑化する
6. 状態の“不変性”と安全な更新
const next = { ...prev, isOpen: true };
- ✅ 状態を直接 mutate しない(再レンダリングが起きない)
- ✅
Object.assign
/ スプレッド構文でコピー更新
7. 状態トリガーの設計と制御
- UI → 状態更新
- APIレスポンス → 状態更新
- タイマー / 外部イベント → 状態更新
✅ 更新元が多い場合は「イベント」として抽象化
dispatch('LOGIN_SUCCESS', payload);
→ ✅ 状態に直接触れず、間接的に制御する構造へ
設計判断フロー
① 状態はローカルUI専用? → useState等で管理
② 状態は複数コンポーネントから参照される? → グローバル管理
③ 状態が明確なフェーズを持つ? → ステートマシン設計
④ 状態の変更元が複数ある? → イベントドリブン化
⑤ 状態が変化する頻度は? → 高頻度ならセレクティブ購読設計
よくある失敗と対策
❌ 状態の責任が不明瞭で“なんとなく共有”
→ ✅ スコープ設計を「誰が持ち」「誰が読んで」「誰が変えるか」で分割
❌ グローバルステートにローカル状態を混在
→ ✅ UI状態(例:開閉)はローカルに留める
❌ 状態の変更に副作用が埋め込まれている
→ ✅ 状態と副作用は分離(例:useEffectで外部反応)
結語
状態管理は単なる変数の保持ではない。
それは**「情報の流れをどう設計し、責任をどこに持たせるか」**という、アーキテクチャの中核そのものである。
- 状態は構造に従い
- 状態変化はルールで制御され
- 状態の読み書きは責任が明確である
設計された状態は、予測可能性と信頼性をもたらす。
状態は“どう持つか”ではなく、“どう変化するか”まで設計すべきである。