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における状態管理の設計戦略:ローカル vs グローバル・Flux原則・データフロー分離の設計指針

Posted at

概要

アプリケーションが崩壊する時、それは「状態の場所」と「状態の流れ」が破綻している。
状態とは、“何が変わるか”ではなく、“どこで持つべきか”を設計する行為である。

本稿では、JavaScript(およびReact/VueなどのSPA環境を前提)において、状態管理の判断軸と設計パターンを以下の観点で解説する:

  • ローカル状態 vs グローバル状態の設計的判断
  • Fluxアーキテクチャの本質
  • 非同期ステート更新とイベント駆動の協調
  • 状態スライスと責務分離
  • 状態と副作用の分離設計

1. 状態の“責務”による分類

✅ ローカルステート

  • UIに閉じている(フォームの開閉、アクティブタブ、ホバー状態)
  • コンポーネントが完結している

✅ グローバルステート

  • ユーザー認証、言語設定、カート情報、フィルタ条件
  • 複数コンポーネント間で共有される“意味的状態”

→ 状態の“利用範囲”ではなく、“意味的責務”で判定すべき


2. Flux原則:状態設計の4原則

Action → Dispatcher → Store → View
  • 単方向データフロー
  • 状態は唯一の正解としてStoreに集約
  • 更新は必ずAction経由
dispatch({ type: 'UPDATE_USER', payload: user });

→ ✅ “状態がどこで、どう変わるか”を1本道で追える構造


3. 状態スライスとスコープ分離

// userSlice.js
const initialState = { name: '', isLoggedIn: false };

function userReducer(state = initialState, action) {
  switch (action.type) {
    case 'LOGIN':
      return { ...state, name: action.payload, isLoggedIn: true };
    default:
      return state;
  }
}
  • ✅ 状態はスライス(単位)ごとに切り出し
  • ✅ reducer/Storeの責務をドメインごとに明確化

4. 非同期アクションと副作用の切り出し

async function loginUser(dispatch, credentials) {
  dispatch({ type: 'LOGIN_REQUEST' });
  try {
    const user = await api.login(credentials);
    dispatch({ type: 'LOGIN_SUCCESS', payload: user });
  } catch (e) {
    dispatch({ type: 'LOGIN_FAILURE', error: e });
  }
}
  • ✅ 副作用(API通信など)はAction内部 or Middlewareに委任
  • ✅ reducerは純粋関数に保つことが原則

5. 状態フローの可視化とデバッグ

  • Redux DevToolsやVue DevToolsで状態の履歴を追える構造
  • “今の状態”ではなく、“状態がどう変化したか”が追えるように設計
  • 状態更新の責務は1つの関数だけが持つように制御

6. 状態の“流れ”に関する設計指針

観点 意図
単方向データフロー どの順番で状態が変化するかを保証する
イベント駆動 状態の変化はユーザー操作 or 副作用によって発火
状態の静的定義 状態の構造は明示的(初期状態・型など)
ストアの分割 状態が増えてもスケーラブルに設計できるようにする

設計判断フロー

① 状態はUIに閉じている? → ローカルstateで完結

② 状態が複数箇所に波及? → グローバルstateとして切り出す

③ 状態変更が曖昧になってきた? → Flux構造で流れを明示

④ 状態が副作用と混在? → 副作用はActionまたはMiddlewareに分離

⑤ 状態が追えない? → DevTools等で履歴をトラック可能に設計

よくあるミスと対策

❌ すべての状態をグローバルに持つ

→ ✅ 意味的責務に基づいて、スコープに応じて分離する


❌ Actionやreducerの肥大化

→ ✅ 状態スライスを責任範囲ごとにモジュール化する


❌ 状態変更がどこから行われているかわからない

→ ✅ “Actionを通す”ことを構造として強制する


結語

状態とは「今どうなっているか」ではなく、「どう変わってきたか」を設計する構造である。

  • UIの背後にある意図
  • 非同期による変化
  • 操作に応じた反応

状態はコードの心拍である。
それを正しく設計することが、アプリケーションに“生命”を与える第一歩である。

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?