見出し画像

Flutterアプリ開発における「状態管理」とは

はじめに

カシオでアプリ開発に携わっている野元です。

コードの可読性およびアプリ自体の機能向上のために、Flutterの状態管理パッケージ:Riverpodについて勉強している最中なのですが、
そもそも「状態管理」「状態」についての理解が浅いあるいは曖昧なのでは?と感じたため、本記事にまとめます。
なるべく平易な形で、自分の中で噛み砕いて表現したものです。本質的な誤りなどはぜひご指摘いただきたいです。

対象読者

  • Flutterで状態管理を行おうとしているものの、そもそも「状態」や「状態管理」についてイメージが湧かない方


「状態」とは

アプリケーションにおいて「状態」とは、ざっくり「変化しうるデータ」です。

「状態管理」とは

ここで、大きくアプリケーションを「画面」「状態」「(それら以外の)メソッド」に分割して考えます。基本的に「画面」「状態」に応じた変化を求められます。また、「状態」はユーザーの操作などをきっかけとして、「メソッド」から変更されます。

ざっくりと分けているので比較的わかりやすいですが、実際のアプリケーションには「画面」「状態」「メソッド」がそれぞれたくさん存在しています。
すると、一つの「状態」を複数の「メソッド」が更新したり、ある「画面」で実施された「状態」の変化により、別の「画面」も変化する…ということが生じる可能性があります。

「状態管理」とは『「状態」をどの「メソッド」で更新するか、どの「画面」が「状態」を参照するか』を管理する考え方/仕組みのことです。


Flutterにおける状態管理の差異

状態管理を定義したところで、Flutterの状態管理パッケージがどのような思想、形式で状態管理を行っているのか、「StatefulWidget」「Provider」「Riverpod」に絞って整理していきたいと思います。

状態管理をFlutterに対して当てはめる場合、上記の「画面」「Widget」と置き換えることができます。

StatefulWidget

FlutterではWidgetそのものに状態を持たせることができます。それがStatefulWidgetです。使い方は非常に簡単で、StatefulWidgetの内部でsetStateを呼び出すことでStatefulで記述されている部分がすべて再描画されます。

『表示に影響がある状態変化が発生したときに、setStateを明示的に行なうことで、新しい値で「Widget」が再構築される』という感じです。

StatefulWidgetはWidgetと状態が合わさっているものなので、非常にわかりやすく簡便なのですが、例え一つの状態の変化をWidgetに反映させる場合でも、全体の再描画が必要なため無駄が多いとされています。
また、一つの状態変化をWidgetに反映させる場合でも全体を再描画しなければいけないことや、別のWidgetに紐づいている状態を参照することはできないことが問題点として挙げられます。

Provider

全体が再描画されてしまうというsetStateの問題点を解消しているのが、状態管理パッケージProviderです。

Providerは状態の変化に対して、Widget全体ではなく変化した部分のみを再描画することが可能です。

また、Providerを使用すると、Widgetが常に状態を監視するような仕組みを作ることが可能です。StatefulWidgetは状態の変化のたびにsetState処理の明示的な動作が必要であるのに対して、Providerでは状態変化に反応して自動でWidgetの更新が行われます。こちらもStatefulWidgetと大きく異なる点です。

さらに、Widgetをツリー構造にすることによって、親Widgetで取得した状態を子Widgetの全てから参照することが可能です。

Riverpod

Providerをさらに拡張した状態管理パッケージがRiverpodです。
大雑把にどこがProviderから拡張されているのか整理します。

先述の通り、Providerを用いれば一つの情報を複数のWidgetで使用できます。
ここで、つい数行前のProviderのまとめを再度書きます。

さらに、Widgetをツリー構造にすることによって、親Widgetで取得した状態を子Widgetの全てから参照することが可能です。

上記記述は、子Widgetで取得した状態を親Widgetで参照することができないという風に読むことができますし、実際にその通りです。
RiverpodではProviderではできなかった『子Widgetで発生した状態変化を親Widgetに自動で反映すること』が可能になります。つまり、どのWidgetからでも全ての状態を取得、参照が可能な仕組みを作ることができるということです。

状態管理の差異:まとめ

Flutterにおける状態管理を整理しました。雑ですがWidgetと状態の個数の対応でまとめると以下のようになります。

  • StatefulWidget:Widgetと状態を1:1で管理する

  • Provider:複数のWidget間で状態を共有する

  • Riverpod:全てのWIdgetで全ての状態を共有する


おわりに

「状態管理」ひいては「状態」とはそもそもなんなのかに始まり、Flutterにおける状態管理の手法の考え方の比較を行いました。

RiverpodのReadmeや使用例を読んだだけでは自分の理解に不安がありましたが、状態管理手法の比較を行い、Riverpodに対する理解が進んだように感じています。

今後は他の言語において、状態管理がどのような思想で行われているのかも調べていきたいと思います。(何かご存じの方はぜひお知らせください)

この記事が参加している募集