速習 Redux
次の章で学習する「Redux Toolkit」をやれば、Redux の細かい概念を知らなくても、Redux によるデータ管理が可能となります。
ただ、Redux Toolkit を使うにしても、Redux に出てくる概念を知っておくことはプラスになります。(Redux Toolkit の公式ドキュメントを理解しながら読み進めやすくなる)
このページでも Redux の概念を簡単に説明しますが、以下の記事ではより詳しく説明されているので、そちらも参考にしていただけたらと思います。
Redux の役割
Redux は「状態管理(State 管理)」を行うライブラリとなります。
「状態管理」を言い換えると「データの保管・データの操作を行うこと」と同じような意味です。
例えば、今回の勉強会で開発していく Todo アプリを例にすると、主なデータは「Todo 情報」となります。
Todo アプリを作る際に、Todo データを Web ページに表示するには、どこかしらに以下のような Todo データを持っておく必要があります。
- Todo データ 1 件 1 件の情報(例: id, タイトル、進捗など)
- Todo データを何件持っているかの情報(Todo の配列)
その管理場所の 1 つの手段として Redux があります。
Redux を使うと何が良いの?
前提
React の Context を使えば Redux と同じようなことができます。しかし、この勉強会は「Redux Toolkit」を扱うので、Redux を使う前提で話を進めていきます。
規模が小さめのアプリ開発であれば Context で十分かと思いますが、知り合いの会社で規模が大きい React アプリのデータ管理で Redux を使っているところがあるので、Redux を覚えることは損にはなりません。
(Redux を覚えれば、React Context の習得難易度も下がるでしょう)
React の Context を詳しく知りたい方は、公式ドキュメントの ADVANCED GUIDES の中にある「コンテクスト」をご覧ください。
また、Context には「useContext」という Hooks も React の標準で備わっています。
Context を学んだら、こちらも覚えておくと良いでしょう。
Redux を使わずに開発の規模が大きくなってくると...
React でデータ管理を行う 1 つの方法としては「useState」というものがあります。
これは、関数コンポーネントでデータ管理を行う際によく使われる Hooks の 1 つの機能となります。
ただ、useState で管理するデータは以下の場面でしか使えません。
- useState を使っているコンポーネント内
- 子コンポーネントに props で渡した場合
- カスタムフックの戻り値経由で受け取った場合
カスタムフックに関しては、React 公式ドキュメントの以下のページをご覧いただけたらと思います。
ただ、アプリケーション全体で共通の state 値を利用したい場合、以下の図ような面倒なことが起きてしまいます。(文字が小さくて読めない場合は、拡大してお読みください)
アプリケーション全体で使いたい共通データの一例として、「ログイン情報」「ユーザーのプロフィール情報」などがあります。
この図が示しているのは、コンポーネントツリーの根っことなる「親コンポーネント」で、アプリケーション全体で使うデータ(state)を管理して、そのデータを利用する「子コンポーネント」「孫コンポーネント」に props 経由でデータを渡している様子となります。
state の値が更新されると、React はその変更を検知して、新しい state の値を使うように再レンダリングする。
単純にグローバルでオブジェクトを持って、それを更新するだけでは再レンダリングされない。(更新を検知して再レンダリングする仕組みを自分で用意するなら話は別)
これの何が問題かと言うと、コンポーネントの数が増えれば増えるほど、データの流れを追うのが大変になってきます。
もし上の図で、「孫コンポーネント 4」しか「親コンポーネント」で管理しているデータを使わないとなったとき、「子コンポーネント 2」自身は「親コンポーネント」のデータを使わないのに、橋渡しのためだけに props で受け取れるようにする必要がでてきます。
さらに言えば、「子コンポーネント 2」の下の「孫コンポーネント」が不要になったとき、誰も「親コンポーネント」のデータを使わなくなるので、props の変更が必要となります。
props を変更せずにそのまま放置しておくと
「どうして子コンポーネント 2 は props で親コンポーネントのデータを受け取っているんだ?子コンポーネント 2 の中では使っていないのに...」
と謎なコードが残り、その原因・理由を追うのに時間を使ってしまいます。
Redux を使うと、props 受け渡し問題が解決する
先ほどの図で、親コンポーネントが管理していたデータを Redux に任せると以下のようになります。
また、あるコンポーネントが Redux にデータの更新を行なった場合、更新対象となったデータを利用している別のコンポーネントは、その更新を自動的に検知してコンポーネントの再レンダリングを行います。
例えば、上の図の「孫コンポーネント 1」がデータの更新を行なったとします。
更新を行なった元々のデータを「孫コンポーネント 4」が使っていたら、「孫コンポーネント 4」は自動的に更新後のデータを受け取って、表示を更新します。
この例を図で示すと以下のようになります。
Redux のデータの更新の流れを細かいところまで理解するには、Redux に出てくる以下の用語・概念の理解が重要となります。
- Action
- Dispatch
- State
- Store
- Reducer
ここらへんに関しては、最初にも共有した以下の記事が参考になるので、より詳しく知りたい場合は、以下の記事も参考にしていただけたらと思います。
React と Redux をつなぐには?
「React Redux」というライブラリを使うことで、React コンポーネントと、Redux のデータ管理をつなぐことができます。
Redux Toolkit 公式ドキュメントの「Tutorials > Quick Start」「Tutorials > TypeScript Quick Start」の中で使うことになるので、次の章で実際に使いながら、使い方のイメージを掴んでいきましょう。
「Redux」そのものはただのデータ管理を行うためのライブラリです。
そのため、React なしでも Redux を使うことはできます。(Redux は React に依存しているわけではない)
ただ、そうはいっても、Redux とセットで使うもので最もポピュラーなものは React だと認識しています。
React と Redux の全体のデータの流れ
以下の図は Redux 内のデータ更新の流れと、React と Redux の繋ぎ込みを示したものです。
さきほども少し話しましたが、上の図でに出てくる「Action」「Store」「dispatch」「Reducer」などは Redux でよく出てくる用語となります。
これらの用語をおさえておきたい場合は、繰り返しになりますが、以下の記事などを参考にしていただけたらと思います。