はじめに
useReducerについての理解が浅かったため、その特徴をuseStateと紐づけて整理しました。
useState
はシンプルで使いやすいですが、複数の状態や依存関係が増えると管理が難しくなります。
そこで登場するのが useReducer です。
この記事では、なぜ useReducer が必要なのか、どのように使うのかを解説します。
useReducerとは?
useReducer は、React が提供するフックのひとつで、
状態とその更新ロジック(reducer関数)をまとめて管理するための仕組みです。
useReducer の基本的な流れ
reducer関数の定義
現在の状態と「アクション」と呼ばれる更新指示を受け取り、新しい状態を返す
純粋関数を定義します。
function reducer(state, action) {
switch (action.type) {
case 'SET_THEME':
return { ...state, theme: action.payload };
default:
return state;
}
}
useReducerの呼び出し
useReducer に初期状態と reducer 関数を渡すと、
現在の状態と React が提供する dispatch 関数が返されます。
// 初期状態を定義
const initialState = { theme: 'light' };
// 先程のステップで定義したreducer関数
function reducer(state, action) {
switch (action.type) {
case 'SET_THEME':
return { ...state, theme: action.payload };
default:
return state;
}
}
// 初期状態とreducerを引数にuseReducerを呼び出す
// useReducerから状態とdispatch(reducer関数を呼び出すための関数)を受け取る
const [state, dispatch] = useReducer(reducer, initialState);
dispatch関数で更新リクエスト
dispatch 関数にアクションオブジェクトを渡すと、
React が内部で reducer 関数を実行し、状態を更新して再レンダリングを行います。
なぜuseReducerを使うのか?
useStateによる状態管理の問題点
-
個別管理の限界
useState
は一つのプロパティの状態管理には適しています。
例えば、テーマの切り替えを管理する場合は以下のように実装できます。const [theme, setTheme] = useState('light'); // テーマを切り替える処理 const toggleTheme = () => { setTheme(prevTheme => prevTheme === 'light' ? 'dark' : 'light'); };
-
複数状態の管理が煩雑
アプリケーションが大きくなると、テーマだけでなくユーザー情報、言語設定、その他多数の状態を個別に管理する必要が出てきます。
その結果、状態更新のロジックがコンポーネント内に分散し、どの更新がどの状態に影響を与えているかを把握するのが難しくなります。
useReducerを使うメリット
-
更新ロジックの集中管理
複数の状態を個別に管理するのではなく、状態更新のロジックを一箇所にまとめることで、
どのアクションがどの状態を更新するか明確に把握できます。 -
依存関係の追跡が容易に
状態間の依存関係がある場合、すべての更新処理を一元化することで、
どの変更が他の状態にどう影響するかを容易に追跡・管理できます。
useStateとの使い分け
useState の場合
- シンプルな状態管理に最適
単一の状態や少数の状態なら、以下のようにシンプルに実装できます
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
setTheme(prevTheme => prevTheme === 'light' ? 'dark' : 'light');
};
useReducerの場合
- 状態管理の一元化
複数の状態を一つのオブジェクトで管理し、更新ロジックを reducer 関数に集約できます。
全ての状態更新が一か所(reducer関数)に集約されるため、どのアクションがどの状態を更新しているかが明確になります。
まとめ
useState
- シンプルな状態管理に適しており、単一または少数の状態更新には手軽に利用できます
- 状態が複雑になった場合、更新ロジックが散在しやすく、管理が困難になります
useReducer
- 複数の状態や依存関係を持つ場合でも、状態更新のロジックを一元化できるため、
コードの可読性と保守性が大幅に向上します - reducer 関数で純粋な状態更新を実装し、dispatch 関数を通じて一元的に更新をリクエストする仕組みが特徴です