Reactアプリケーションの状態管理について
どれを使うべきか?
大抵のケースにおいては、まずこの手法で十分でないかを検討するとよいのではないかと思います
Context
個人的には、Contextを状態管理に使うのは出来るだけ避けた方がよいと思っています
もし使うなら、readonlyな値の共有などに留めておくとよいのではないかと思っています
個人的には、初手でこれらを入れる必要はなくて、必要になったタイミングで導入するのでも十分だと思います
Reduxは使用がやや面倒くさいという意見などもあるとは思いますが、グローバルステートの管理手段としては以下の点などから、現時点では最も優秀だと個人的には思っています (ただし、小規模なアプリケーションにおいては過剰になりがちだとも思うため、すべてのアプリケーションにマッチするわけではないと思います)
Reduxにおける
reducerは独立した純粋関数であるため、容易にユニットテストが記述できる
成熟度
エコシステムの充実度合い
グローバル状態の管理をストアに分離/カプセル化でき、ストアの外からは自由に状態を更新できないため、状態の意図せぬ不整合によるバグを防止しやすいのがメリットです
例えば、
Reduxの場合、
actionを明示的に
dispatchしないと状態を更新できず、また状態の更新そのものも
reducerに任されるため、
reducerの実装にバグがない限り、グローバル状態において意図せぬ不整合が発生する事態を避けられます (また、
reducerは純粋関数であり、容易に独立してユニットテストの記述が可能です)
複雑な状態管理が必要な場合に適している (ある状態が複数の箇所から更新される場合や状態の不整合が起きてしまうと困る領域など)
アプリケーションのあらゆる状態を
Storeで管理する必要はなく、用途に応じてその他の手法(例:
useState, Server Stateなど)と併用するとよいと思います
これらはStoreやAtomic State Management系統のライブラリと比較して用途がハッキリしており、乱用してしまうリスクも低いと考えられるため、プロジェクトの初期で導入してもよいと思います
正直なところ、どういった場面でこれらを使うと効果的なのか、自分はまだ判断がついていないです
ただ
Jotaiは開発が非常に活発な印象があるので、今後も様子を見ていきたい
個人的な考えとしては、グローバルステートを無闇に使うのはよくないとできるだけ避けた方がよいと考えており、これらのライブラリは非常に手軽で使い勝手が良い分、乱用されてしまうリスクはあるのではないかと思っています
もしグローバルステートを導入するにしても、特に複数の箇所から変更されるような場合は慎重に取り扱った方がよいと思うので、そういった場面ではStoreの方が適しているとは思う
とはいえ、必要に応じてStoreと使い分けることもできたりはすると思うので、
Jotaiや
Recoilなどは各種
Storeライブラリとは別物と考えるのがよいのかもしれないと思いました
グローバルステートの取り扱いについて
まず、個人的にはグローバルステートは無闇に導入するのは避けた方がよいと考えています
ただし、Server Stateについては管理が複雑なので、これについてはプロジェクトの初期から
React Queryや
SWRなどを導入してものよいと考えています
もしProps Drillingで十分な場合は、まずはそちらで対処するのがよいと思っています
Props Drillingが面倒という動機でグローバルステートを導入してしまうと、
結合度が増加してしまい、却って品質が低下してしまうことも考えられます (必要な情報を引数で渡さず、実質的にグローバル変数を介してやり取りすることになるため)
バケツリレーによりあまりにも階層が深くなってしまう場合には、グローバルステートを導入する前に、まずは
Component Compositionや
Render propsなどの手法を使って解消できないか検討するとよいのではないかと思っています
とはいえ、小〜中規模ぐらいの規模であれば、あまり気にせずにグローバルステートを導入してしまっても、ワークはするとは思います
関連リソース/参考リンク
各状態管理ライブラリの比較
Store
Atomic State
Server State
フォーム
その他
パターン
Hooksを用いた状態管理について
バケツリレーに関する話
関連ページ