useReducerとは?
useState
よりちょっと賢い「状態管理の方法」- 「どう変えるか?」のルールを
reducer
という関数にまとめて管理する - 状態が増えてもスッキリ書ける🐾
useReducerの使い方
少し複雑ですので、まず実際のコードで見ていきます。
まずはuseReducerを使わない、カウンター
app/components/CounterState.js
import { useState } from "react";
function CounterState() {
const [count, setCount] = useState(0);
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
<button onClick={() => setCount(count - 1)}>-1</button>
</div>
);
}
export default CounterState;
次にuseReducerを使ったカウンター
app/components/CounterReducer.js
"use client";
import { useReducer } from "react";
// ✅ 1. ルール(reducer)を作る
function reducer(state, action) {
if (action.type === "increment") return { count: state.count + 1 };
if (action.type === "decrement") return { count: state.count - 1 };
return state;
}
function CounterReducer() {
// ✅ 2. `useReducer` を使う
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<p>カウント: {state.count}</p>
{/* ✅ 3. ルールに従って変更を指示する */}
<button onClick={() => dispatch({ type: "increment" })}>+1</button>
<button onClick={() => dispatch({ type: "decrement" })}>-1</button>
</div>
);
}
export default CounterReducer;
コンポーネントを読み込んで表示します。
app/page.js
import CounterState from "./components/CounterState";
import CounterReducer from "./components/CounterReducer";
<CounterState />
<CounterReducer />

下図のように同じ動きをするカウンターが表示されています。

コード解説
順番が前後しますが、下記の部分でuseReducerを設定しています。
const [state, dispatch] = useReducer(reducer, { count: 0 });
これは下図のようになっています。

書き方のほとんどがuseStateと同じですが、「reducer」という「ルールを定めた関数」が付け足されています。
reducerはこの部分で定義されています。
function reducer(state, action) {
if (action.type === "increment") return { count: state.count + 1 };
if (action.type === "decrement") return { count: state.count - 1 };
return state;
}
渡ってきた「type」の値によって処理を分岐しています。
ここではわかりいやすいようにif分で分岐していますが、一般的にはswitch分で記述します。
(:例文
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
return state;
}
}
JSXではボタンクリックでそれぞれのtypeの値に応じた更新用関数が動きます。
<button onClick={() => dispatch({ type: "increment" })}>+1</button>
<button onClick={() => dispatch({ type: "decrement" })}>-1</button>
このように「ルールを定めた関数」に一つのstateに対して異なる動きをする更新用関数をまとめて記述できるのが特徴です。
また、reducer,state,action,dispatch,typeの関数名や値の名前は自由に記述できます。
但し、上記のように記述するのが一般的なので、「useReducerの公式」という風に捉えて、一連の書き方と使い方をセットで覚えておいてください。
React Hooks まとめ
これまで学習してきたHooksの特徴と使い所をまとめました。
Hook | 特徴(できること) | 使い所(いつ使う?) |
---|---|---|
useState | ✅ コンポーネントの状態(データ)を管理 ✅ setState で値を更新 | 🔹 カウンターや入力フォームの状態管理 🔹 ボタンのON/OFFやトグルの管理 🔹 API送受信用のデータ管理 |
useEffect | ✅ 副作用(データ取得・イベント登録)を管理 ✅ コンポーネントの「マウント」「更新」「アンマウント」に対応 | 🔹 API からのデータの送受信 🔹 イベントリスナーを登録・削除するとき 🔹 ページのタイトルを変更するとき |
useRef | ✅ DOM の参照を取得して操作 ✅ レンダリングなしでデータを保持 | 🔹 input や video にフォーカスを当てる🔹 スクロール位置を取得・管理する 🔹 カウントや値を更新しても再レンダリングさせたくないとき |
useContext | ✅ コンポーネント間でデータを簡単に共有 ✅ props のバケツリレーを解消 | 🔹 テーマ(ダークモード・ライトモード)の管理 🔹 ログイン情報の管理(ユーザー名・メールアドレス) 🔹 言語設定(i18n)をアプリ全体で共有 |
useReducer | ✅ useState よりも複雑な状態管理を整理✅ 状態の変更ルールを reducer にまとめる | 🔹 カートやフォームの状態管理(追加・削除・リセット) 🔹 ログインの状態管理(ログイン・ログアウト・トグル) 🔹 useState では管理が複雑になりそうなとき |
コメント