2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptにおける状態管理の設計:ローカル・グローバル・ステートマシンによる予測可能性と一貫性の確保

Posted at

概要

状態(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で外部反応)


結語

状態管理は単なる変数の保持ではない。
それは**「情報の流れをどう設計し、責任をどこに持たせるか」**という、アーキテクチャの中核そのものである。

  • 状態は構造に従い
  • 状態変化はルールで制御され
  • 状態の読み書きは責任が明確である

設計された状態は、予測可能性と信頼性をもたらす。
状態は“どう持つか”ではなく、“どう変化するか”まで設計すべきである。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?