僕は今年、他業種から転職し記念すべき一つ目のアプリケーションの作成に利用したのがReactで思い入れのある言語の一つです。
Reactは非常に拡張の多い言語で、数年で大きな進化を遂げてきました。
いざ、1からReactを始めるにあたって、避けて通れない部分が状態管理です。Reactでの状態管理は外部ライブラリを含めて沢山存在しおりそのドキュメントも多数存在しています。その上で**「実際どれを参考にすればいいのか?」**という部分で非常に苦労をした背景からこちらの記事を書こうと思いました。足りな部分等ご指摘頂けると幸いです。
###まずは簡単なReactのご紹介
ReactはFacebookを中心とした、コミュニティによって開発されたJavascriptライブライリです。SPAなどの構築を得意としています。
SPAで良く比較されるのが、angularとVueです。それぞれの良さがありますが、普及率としては、Reactが人気を博しています。
特性としては、Reactでは状態管理が単方向バインディング(データの流れが一方向)として設計されており、データの流れや状態が管理・把握しやすい設計となっています。またReactのコンセプトとなるcomponent(構成要素)として小単位での設計を行うことで、シンプルな状態管理や、componentの再利用が可能となり、大規模アプリケーションへの準じ拡張が可能であったり、typescriptとの相性がいい事で型の安全性も担保で来ます。
Reactの状態管理(state管理)とは。。。?
文字通り、状態のことを指しています。 ユーザーがログインしているのか?の状態であったり、入力フォームの値の状態等を示します。Reactでは、状態管理をどのように行うかで、全体の構成やライブラリ選定に大きく影響します。
シンプルなReactはstateがバケツリレー式なため、構成が深くなればなるほど、イベント発生時の状態の受け渡しが非常に困難となってしまいます。。。。そういった問題に対する、状態管理方法をご紹介します。
___
##Reactの状態管理方法
###useContext
React16.8からhooksでの利用が可能になっています。Reactの標準機能なので、わざわざ別のライブラリをインポートしたりせずとも利用できるのが最大の特徴であると思います。
使用方法は、createContextでオブジェクトを作成し一元管理。(オブジェクトは複数作成可能。)providerで括る事で、配下のコンポーネントで参照が可能となります。
更新頻度が低い状態管理の小規模のアプリケーションには最適だと思います。
useContextを使用することで、配下の状態変更が用意となるものの、、、デメリットとしては、状態が更新されたらオブジェクトに依存する一連のコンポーネントが全てレンダリングされてしまうという点です。その為、大規模になればなるほどパフォーマンスの問題が発生してしまいます。
###Redux
言わずと知れたReactでの状態のディファクスタンダードであるReduxです。
Fluxフローの概念に基づき、Action→ActionCreater→Reducer→storeとデータの流れが一方向になります。その為、状態変化が追いやすいのが特徴です。
管理している値が変化すると、対象のコンポーネントのみ再レンダリングされるので、useContextのような問題は発生しません。 ディファクスタンダードである分、参考になるドキュメントが豊富なのも魅力です。
問題点としては、手続きが多く非常に面倒である。。。という点です。
上記のようにReactと切り離して状態を管理しますが、Reduxだけで新たに5つの要素(Container・Action・Reducer・Store・Conncect)が存在しています。
その為、コードの記述量が増えたり、ファイル数が増えてしまうのは避けらません。なかなか手軽に導入は難しいですね。
中規模以上のアプリケーションや、順次拡張を行う予定のアプリケーションには適していると思います。
ちなみにReduxを使用する場合は、re-ducksパターンをディレクトリ構成に使用すると便利です。
re-ducksパターンは1機能を1ディレクトリで管理する方法でメリットとしては、
- 構成がシンプルになる。
- ファイルが肥大化しない。
- ファイルごとの役割が明確になる。
等があり、お互いの影響範囲が少ないのでチームでの拡張もしやすくなります。
デメリットとしては、エクスポートするので関数名を考えるのがで面倒であったり、ファイルを分ける分インポートの記述も増えることがありました。
Recoil
RecoilはReact同様Facebook社が開発した状態管理ライブラリです。
状態を各コンポーネントないでAtomとして宣言し、以降は使用したいコンポーネント間で使いまわすことが出来ます。
RecoilはuseContextの問題点を解消する形で提供されており、Redux同様に依存するコンポーネントが全てレンダリングされることもありません。
ReduxとRecoilの違いは、Reduxの状態がcombineReducersによって全てまとめられ一元管理されるのに対して、Recoilは状態が各コンポーネントで宣言され分散管理されます。ここらへんは、Reactのコンセプトである、「component(構成要素)として小単位での設計し組み合わせる」という純正に近い方針だと感じました。
また、標準で非同期処理の扱いが可能であったり、hooksとの相性の良さを念頭に開発されている。
デメリットとしては、現在のver.0.1.1 実験段階であり、公式サポートされていない点でしょうか。。。
非常に利用しやすく、いいところ寄せ集めた感じです。今後の主流になるのでは!?とも感じます。
####結論
現状ReduxとRecoilの人気は同じくらいになっています。今後の動向が楽しみです。
これ以外にも、react-query(非同期処理に重きを置いたライブラリ:キャッシュとして状態保存)など沢山の新たな技術が誕生しています。
Twitter等では、Reduxの時代は終わりか?など言われたりもしていますが、まだまだ利用されてる場面は多いと思います。
それぞれに良さがあり、それを理解したうえで何を採用するのかが重要であり面白い部分だと感じています。日々進歩する技術動向を追うのは本当に大変ですね。。。。(笑)
###まとめ
いかがだったでしょうか?今回は状態管理に限定して、記載しましたが他にも考慮すべきことは沢山あります。またどこかでお話できる機会があれば嬉しいです。
今日はこれで、おしまいです。最後まで読んでいただきたいありがとうございました。