ある程度の大きさのReactアプリを作る際に選択しないといけないものとしてステート管理方式があります。以前React用ステート管理2020 〜Recoilを試してみました〜に書いたように、主要なステート管理には
- ReactのuseStateのみを使う
- ReactのuseReducerとContextを使う
- Redux(元祖Redux)
- Redux Toolkit
- MobX
- Recoil
- StateX 上の記事にはありませんが、有限状態機械(有限オートマトン)をベースにしたステート管理ライブライリーです
ネットの記事等からの感じでは、新規プロジェクトではReactのuseReducerとContextを使うが多いのでしょうか?
小規模ならuseStateのみを使う
小規模なアプリなら下の図のようにuseStateでステートを作り、その値を、子・孫コンポーネントにパラメーター(Props)で渡します。ステートを変更する関数(アクション)も同様にパラメーターで渡し、子・孫コンポーネントからも呼び出せるようにします。
ステートの受け渡しが大変になったらContext(useContext)
ステートの値やアクションをパラメーターで渡すのは面倒です。孫コンポーネントが値を必要な場合は、子コンポーネントで利用されなくてもパラメーターとして渡す必要があります。規模が大きくなってくるとこれらのコード量もばかになりませんし、メンテナンス性も下がります。
そこでReact16.3で導入されたContextを使うと、パラメーターのバケツリレーも不要になり、ステートやアクションが必要なコンポーネントのみがグローバル変数的なContextから値を取得できるようになります。
ステート変更がバラバラにならないようにuseReducer
さらに、ステートを変更する関数(アクション)が多数ありロジックを含む場合は、アクションを一カ所にまとめた方がメンテナンス性も上がります。このステートを変更する関数をまとめたものがリデューサー(Reducer)で、それを実現するためのHookがuseReducerです。
アクションを利用する側もdispatch({type: 'pon', human: Te.Guu})
のようにアクションのタイプと引数を渡すだけで簡単に呼び出せます。
Reduxの悲しい歴史
useReducerのリデューサー(Reducer)はReduxが生み出した概念です、ステートを変更する操作の入り口のアクション(Action)もReduxが生み出した概念です。
Reduxを導入すると下の図のように、ステート管理をReactコンポーネントから分離でき、メンテナンス性の高いアプリを作れます。Redux(元祖Redux)は素晴らしい概念です。
しかし 使うためにはたくさんの面倒なコードを書く必要がありました。またリデューサーではステートの変更処理をイミュータブル(immutable)、破壊的な変更を行わないコードで書かないといけないというJavaScript(プログラミング)初学者には難しい要求を科しています。
一時期 Reactでアプリを作るのなら絶対Reduxを使うべきというようなブログ等がたくさん書かれていました。それを真に受けて、元祖Reduxを使い酷いめにあった人もいるかも知れません。そんな時にReactチームがContextやuseReducerをリリースされ、こんどはRedux is deadというようなブログ等が書かれだし、Redux熱は一気に冷めた感じがします。
Redux Toolkitは、良いRedux
Redux Toolkitは、まったく新しいReduxです。 Redux Toolkitは元祖Reduxとはまったく違い、useReducer+Contextより簡単にステート管理ができるライブライリーだと私は思います。その理由は:
1. 作り方が決まっていて導入しやすい
useContextやuseReducerは自由度が高いとも言えますが、どのように使うを考えないといけません。ステートをContextに置きますので、全ステートを1つのコンテキストに置くと、たくさんのコンポーネントでuseContextする事になり、そのコンポーネントで使ってないステートの変更でも再表示が起きてしまいます。Context分ける場合は、どのように分けるか設計しないと行けませんし、コードも増えます。
Redux ToolkitではステートはReduxが集中管理しているので、あまり考える必要はありません。またリデューサー(Reducer)の書き方も決まっているので、誰が書いても同じようになります。
2. ステートの変更はイミュータブルでなくても良い
Redux Toolkitは標準でImmerライブライリーが組み込まれていて、リデューサー(Reducer)のコードはイミュータブルでなくても構いません。pushなどの破壊的メソッドも使え、JavaScript(プログラミング)初学者の書いたコードでも問題は起きません。(もちろんuseReducerにImmerを導入する事はできますが・・・)
3. 非同期処理も簡単に組み込めます
Redux ToolkitにはcreateAsyncThunkという非同期処理をためのAPIが用意されています。元祖ReduxからあるRedux Thunkと同じようなもので、サーバー通信などを処理を簡単に組み込めます。
4. デバッグも楽
ステートやアクションは完全にReduxで管理されているので、Chrome拡張Redux DevToolsや、 Redux middlewarのLogger for Reduxを使う事で、各アクションでどのようにステートが変化したかが簡単に確認でき、デバッグが楽になります。
5. 欠点は@reduxjs/toolkit
のインストールが必要な事だけ
Redux Toolkitの欠点は@reduxjs/toolkit
をインストールしないといけない事でしょうか?後はReduxのTutorialsを読み、試すだけです。
まとめ
Redux Toolkitに関する(日本語)情報はそれほど多くないかもしれませんが、Redux Toolkitは良いReduxなので是非使ってみてください。