【ITニュース解説】React学習ログ No.5
2025年09月23日に「Qiita」が公開したITニュース「React学習ログ No.5」について初心者にもわかりやすく解説しています。
ITニュース概要
Reactの`useReducer`は、リデューサをコンポーネントに追加するためのフックだ。これにより、より複雑な状態ロジックを効率的に管理できる。使い方は、コンポーネントのトップレベルで`useReducer`を呼び出すのが基本だ。
ITニュース解説
Reactは、Webアプリケーションのユーザーインターフェース、つまり画面上の見た目や操作部分を構築するためのJavaScriptライブラリである。システムエンジニアを目指す上で、Reactは非常に重要な技術の一つだ。Reactでは、コンポーネントと呼ばれる小さな部品を組み合わせてUIを作り上げるが、これらのコンポーネントは、ボタンが押されたり、テキストが入力されたりするたびに、その内部の状態を変化させる必要がある。例えば、ある要素が表示されているか非表示か、カウントがいくつになっているか、といった情報は「状態」として管理される。この状態をいかに効率的かつ安全に管理するかが、React開発において非常に重要な課題となる。
Reactには、コンポーネントの状態を管理するための特別な機能が用意されており、これらは「フック」と呼ばれている。フックとは、関数コンポーネントと呼ばれる種類のコンポーネント内で、状態を管理したり、ライフサイクルといったReactの特別な機能を利用したりするための関数だ。最もシンプルで広く使われる状態管理フックはuseStateである。これは、数字や文字列、真偽値といった単一の値を管理するのに適しており、直感的に利用できる。
しかし、アプリケーションが成長し、状態が複雑になると、useStateだけでは限界が見えてくることがある。例えば、複数の関連する状態を一度に更新する必要がある場合や、状態の更新ロジック自体が複雑になり、コンポーネントのコードが読みにくくなったり、エラーが発生しやすくなったりする場合だ。このような状況に対応するために、ReactはuseReducerという別の状態管理フックを提供している。
記事に「リデューサ (reducer) をコンポーネントに追加するための React フック」とあるように、useReducerの核心は「リデューサ」という概念にある。リデューサとは、現在のコンポーネントの状態と、どのような変更を行いたいかを示す「アクション」と呼ばれる情報を受け取り、新しい状態を計算して返す、純粋な関数である。純粋な関数というのは、同じ入力が与えられれば常に同じ出力が返され、かつ外部のデータに副作用を与えない(つまり、外部のデータを直接変更しない)という特性を持つ関数のことだ。これにより、状態の更新ロジックが予測可能で、信頼性の高いものとなる。
リデューサを使うことで、状態を更新するための複雑なロジックをコンポーネントの本体から分離し、独立した関数として定義できるようになる。これにより、コンポーネント自体はUIの表示に集中し、状態の具体的な変更方法はリデューサに任せることができるため、コードの役割分担が明確になり、可読性や保守性が大きく向上する。
useReducerの基本的な使い方は、コンポーネントのトップレベルで呼び出すことだ。具体的な呼び出し方は、const [state, dispatch] = useReducer(reducer, initialState); のようになるのが一般的である。ここで使われている要素を詳しく見ていこう。
まず、useReducerに渡す最初の引数は、先ほど説明したリデューサ関数そのものである。この関数は、コンポーネントの状態をどのように更新するかという具体的な手順を定義する役割を担う。
次に、第二引数はinitialStateで、これはコンポーネントが最初に画面に表示されるときの状態の初期値を設定するものだ。例えば、カウンター機能であれば初期値を0に、TODOリストであれば空の配列に設定するといった具合である。
useReducerが返してくれるものも重要だ。これは2つの要素を含む配列で、最初の要素はstateと呼ばれる。このstateは、常に現在のコンポーネントの状態を表す変数であり、UIはこのstateの値に基づいて描画される。
配列の2番目の要素はdispatch関数である。このdispatch関数こそが、実際に状態を更新するためのトリガーとなる。コンポーネント内で状態を変更したいとき、開発者はこのdispatch関数を呼び出し、引数として「アクション」を渡す。
アクションとは、どのような状態変更を行いたいかをリデューサに伝えるためのオブジェクトである。通常、アクションオブジェクトにはtypeというプロパティが含まれており、これが「今、何が起こったのか」「どのような種類の変更を要求しているのか」を示す文字列(例: 'INCREMENT'や'DELETE_ITEM'など)となる。また、状態変更に必要な追加情報、例えばTODOリストに追加する具体的なテキストの内容なども、アクションオブジェクトの別のプロパティとして含めることができる。
dispatch関数がアクションを受け取ると、Reactは内部的にそのアクションと現在のstateをリデューサ関数に渡す。リデューサ関数は、これらの情報をもとに新しいstateを計算し、その新しいstateがReactによってコンポーネントに反映される。これにより、コンポーネントは新しいstateに基づいて再レンダリングされ、画面上のUIが更新されるという仕組みである。
useReducerを利用するメリットは多岐にわたる。一つは、複雑な状態の更新ロジックを一か所に集約できるため、コード全体の見通しが良くなり、理解しやすくなる点だ。複数のuseStateでバラバラに管理されていた関連する状態を、一つのリデューサでまとめて扱うことで、状態間の一貫性を保ちやすくなる。二つ目のメリットは、リデューサが純粋関数であるため、テストが非常に容易であることだ。特定のアクションと初期状態を与えれば、どのような結果になるかが常に予測できるため、開発者は安心して単体テストを記述できる。三つ目として、dispatch関数はコンポーネントが再レンダリングされても同じ参照を保つ性質があるため、子コンポーネントにdispatch関数を渡す際に、不要な再レンダリングを防ぎ、パフォーマンスを最適化できる場合がある。
useStateとuseReducerのどちらを使うべきかという疑問はよく聞かれるが、基本的な指針としては、単純で独立した状態を管理する場合にはuseStateが最もシンプルで直感的である。しかし、複数の状態が密接に関連しており、それらをまとめて複雑なロジックで更新する必要がある場合や、次の状態が前の状態に大きく依存するようなケースでは、useReducerが非常に強力なツールとなる。例えば、複数の入力フィールドを持つフォーム、ステップを順に進んでいくウィザード形式の機能、あるいはゲームの盤面のような複雑なデータ構造を扱う際に、useReducerはその真価を発揮するだろう。
システムエンジニアとしてのキャリアをスタートする上で、Reactにおける状態管理の選択肢とその使い分けを理解することは非常に重要だ。まずはuseStateから始めて、より複雑な状態管理の課題に直面したときに、useReducerの導入を検討してみるのが良いアプローチとなる。useReducerは、より堅牢でメンテナンスしやすいアプリケーションを構築するための強力なツールであり、使いこなすことであなたの開発スキルは確実に向上するはずだ。