React useReducerによる複雑な状態管理 — フォーム、ステートマシン、Reduxパターン
Reactの複雑な状態管理のためにuseReducerをマスターします。フォーム状態、ステートマシン、useContextとの組み合わせによるグローバル状態、useReducerとuseStateの選択基準を網羅。
State Hooks
詳細な説明
useReducerによる複雑な状態管理
useReducerはuseStateの代替で、複雑で相互依存する状態遷移の管理に優れています。
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を使用します。