React useReducerによる複雑な状態管理 — フォーム、ステートマシン、Reduxパターン

Reactの複雑な状態管理のためにuseReducerをマスターします。フォーム状態、ステートマシン、useContextとの組み合わせによるグローバル状態、useReducerとuseStateの選択基準を網羅。

State Hooks

詳細な説明

useReducerによる複雑な状態管理

useReduceruseStateの代替で、複雑で相互依存する状態遷移の管理に優れています。

useReducerを選ぶタイミング

  • 状態に一緒に更新される複数のサブ値がある
  • 次の状態が前の状態に依存する
  • 状態ロジックを集約してテストしたい
  • dispatch(安定した参照)を深い子に渡す必要がある

フォーム状態の例

interface FormState {
  name: string;
  email: string;
  errors: Record<string, string>;
  submitting: boolean;
}

type FormAction =
  | { type: "SET_FIELD"; field: string; value: string }
  | { type: "SET_ERRORS"; errors: Record<string, string> }
  | { type: "SUBMIT_START" }
  | { type: "SUBMIT_SUCCESS" }
  | { type: "RESET" };

function formReducer(state: FormState, action: FormAction): FormState {
  switch (action.type) {
    case "SET_FIELD":
      return { ...state, [action.field]: action.value, errors: {} };
    case "SET_ERRORS":
      return { ...state, errors: action.errors, submitting: false };
    case "SUBMIT_START":
      return { ...state, submitting: true, errors: {} };
    case "SUBMIT_SUCCESS":
      return { name: "", email: "", errors: {}, submitting: false };
    case "RESET":
      return { name: "", email: "", errors: {}, submitting: false };
  }
}

ステートマシンパターン

useReducerは自然にステートマシンにマッピングされ、不可能な状態を不可能にします。

useReducer + useContextによるミニRedux

useReducerをuseContextと組み合わせて、外部ライブラリなしでグローバル状態コンテナを作成できます。dispatch関数はコンテキスト経由で渡します -- 安定したIDを持ち、不要な再レンダリングを引き起こしません。

ユースケース

マルチステップフォーム、ショッピングカート、データ取得ステートマシン、集約されたテスト可能な状態遷移が必要なあらゆるシナリオにuseReducerを使用します。

試してみる — React Hooks Reference

フルツールを開く