見出し画像

【複雑なStateを撃退!】React の useReducer で作る「予測可能」な状態管理。useState からの卒業


85日目にカスタムHookでロジックを切り離す技を学び、コードがだいぶスッキリしてきたはずです。

本日86日目は、Reactの状態管理の「もう一つの柱」、「useReducer と複雑な State 遷移」を学習します。 「Stateが複雑すぎて、あちこちで更新してバグが起きる…」そんな悩みを、「Reduxのミニチュア版」 とも言える useReducer で鮮やかに解決しましょう!

🏷️はじめに:その「useState」、絡まっていませんか?

useState は便利ですが、Stateの中にオブジェクトや配列があり、それを「条件によってあれこれ書き換える」ようになると、コードが複雑になりがちです。

  • 「あれ?このタイミングでこの変数はどうなるんだっけ?」

  • 「あちこちのボタンで同じような更新ロジックをコピペしている…」

そんな時、「Stateの変更方法を1箇所に集約する」 仕組みが useReducer です。


💡 1. useReducer の基本概念

useReducer は、「アクション(指示書)」を投げると、「Reducer(計算係)」 が今のStateを見て新しいStateを返す、というルールで動きます。

  1. Dispatch: 「こういうことして!」という指示(Action)を投げる。

  2. Reducer: 「なるほど、それなら今の状態はこう変わるね」と計算する。

  3. State Update: 新しいStateに差し替わる。

💻 実装例:カウントアップ・ダウンをReducerで管理

const initialState = { count: 0 };

// 💡 Reducer: 「現在の状態」と「指示」を受け取って「新しい状態」を返すだけ
function reducer(state, action) {
  switch (action.type) {
    case 'increment': return { count: state.count + 1 };
    case 'decrement': return { count: state.count - 1 };
    case 'reset': return { count: 0 };
    default: throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <>
      Count: {state.count}
      {/* 💡 あとはdispatchを呼ぶだけ */}
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
    </>
  );
}

💡 2. なぜ useState ではなく useReducer なのか?

  • ロジックの分離: 更新処理(Reducer)をコンポーネントの外に出せるため、テストが非常に簡単になります。

  • 予測可能性: 「ボタンA」を押しても「ボタンB」を押しても、同じ dispatch を使うので、状態遷移のルールが一貫します。

  • 複雑性の解消: useEffect で無理やり複数のStateを同期させる必要がなくなり、1つのReducerで全ての状態を管理できます。


📝 86日目のまとめと課題

✅ 本日の習得ポイント

  • Reducer関数: 「今の状態 + 指示 = 次の状態」という純粋な計算処理。

  • Dispatch: コンポーネント側からは「何をしたいか(type)」を伝えるだけにする。

  • 状態の集約: 複雑なデータ構造の更新を一手に引き受ける役割。

📝 86日目の課題

  1. 「Todoリスト」のような、追加・削除・完了といった複数の操作があるコンポーネントを useState で作っていたら、それを useReducer に書き換えてみてください。

  2. Reducer関数だけを取り出して、Vitestで「正しいアクションを送れば正しいStateが返るか」をテストしてみてください(すごくテストしやすいはずです!)。

もっとReactを学びたい人はここから!

#駆け出しエンジニアと繋がりたい #プログラミング学習 #React #100DaysOfCode #今日の積み上げ

いいなと思ったら応援しよう!