useReducerは、Reactで複雑な状態管理を行う際に便利なフックです。
特に、複数の状態をまとめて管理したい場合や、状態を一つの流れで処理したい場合に役立ちます。
useStateよりも少し高度な状態管理が必要なときに使うことが多いです。
1. useReducerの基本
useReducerは、現在の状態と”アクション”に基づいて新しい状態を生成します。使い方は、通常のuseStateと似ていますが、useReducerは”リデューサー関数”と呼ばれる関数で状態を更新します。
const [state, dispatch] = useReducer(reducer, initialState);
-
reducer: 現在の状態とアクションを受け取り、更新後の状態を返す関数。
-
initialState: 初期状態。
-
dispatch: アクションを送信するための関数。
2. useReducerの使い方
以下の例では、カウンターを増減する処理をuseReducerで管理しています。
import React, { useReducer } from 'react';
// リデューサー関数
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
}
const Counter = () => {
const initialState = { count: 0 };
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>カウント: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>増やす</button>
<button onClick={() => dispatch({ type: 'decrement' })}>減らす</button>
</div>
);
};
export default Counter;
3. 各要素の説明
-
リデューサー関数 (reducer): 状態とアクションを元に次の状態を返す関数です。switch文でアクションの種類を分け、それに応じた状態の変更を行います。
-
dispatch関数: この関数でアクション(type)をリデューサー関数に送信し、状態を更新します。例えばdispatch({ type: ‘increment’ })のように使います。
4. useReducerを使うメリット
-
複雑な状態管理が簡単に: 状態が多くなったり、条件によって多段階の変更が必要な場合に、コードが整理され、可読性が向上します。
-
switch文による管理: アクションタイプごとに状態遷移を一元管理できるため、変更がわかりやすくなります。
-
状態の一貫性: useReducerは、状態管理の一連の流れを中央で処理できるので、予測可能で一貫性のある状態管理が可能です。
5. より複雑な例
たとえば、addItem、removeItem、clearItemsといった複数のアクションが必要な場合、useReducerで状態管理が効率化できます。
import React, { useReducer } from 'react';
const initialState = { items: [] };
function reducer(state, action) {
switch (action.type) {
case 'addItem':
return { items: [...state.items, action.payload] };
case 'removeItem':
return { items: state.items.filter(item => item.id !== action.payload) };
case 'clearItems':
return { items: [] };
default:
return state;
}
}
const ItemManager = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<button onClick={() => dispatch({ type: 'addItem', payload: { id: 1, name: 'アイテム1' } })}>
アイテムを追加
</button>
<button onClick={() => dispatch({ type: 'removeItem', payload: 1 })}>
アイテムを削除
</button>
<button onClick={() => dispatch({ type: 'clearItems' })}>
すべてクリア
</button>
<ul>
{state.items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
};
export default ItemManager;
まとめ
-
useReducerは複雑な状態管理に適している: 1つの状態をさまざまな方法で操作したい場合に便利です。
-
アクションタイプで処理を分ける: 状態更新を一貫して管理するために役立ちます。
-
dispatchで状態変更を簡潔に: dispatchで一つの関数で異なる操作を実行でき、コードがシンプルになります。
useReducerを適切に活用すると、
複雑な状態を効率的に管理しやすくなるので、
Reactの状態管理をより理解し、効果的にコントロールするためにおすすめのフックです。
コメント