■状態管理について
状態管理は非同期処理で重要
- IOの読み込み中、読み込み完了、成功/失敗
- プルリフでユーザーが引っ張ったことを検知->リフレッシュ->反映
- 無限スクロール->一番下に来たことを検知->読み込み中->表示
- サジェスト(入力値をリアルタイムで取得、候補を非同期で取得->表示)
- 楽観的UI(DBに登録する前にユーザーへ偽データで表示)
■Flutterの状態管理
StatelessWidget:
固定文言や画面要素が固定の静的画面で用いる。
class STLClassName extends StatelessWidget {
// keyはwidgetが再構築されるときに同一性をチェックするのに利用
const STLClassName({super.key});
// 画面を構築・描画する処理
// コンストラクタ実行後に一度だけ呼ばれる
@override
Widget build(BuildContext context) {
// この中にUIを定義
return const Scaffold();
}
}
StatefullWidget:
画面のコンポーネントに変化がある動的画面で用いる。
class STFClassName extends StatefulWidget {
const STFClassName({super.key});
// 呼ばれるたびに新しいStateオブジェクトが生成され、ウィジェットのライフサイクルの中で状態を保持
// ここではオブジェクトの生成のみ
@override
State<STFClassName> createState() => _STFClassNameState();
}
// 実際の状態管理はこちらに定義する
class _STFClassNameState extends State<STFClassName> {
// 画面を構築・描画する処理
// オブジェクト生成時、setState()後に実行される
@override
Widget build(BuildContext context) {
return const Scaffold();
}
}
<初回画面構築時>
コンストラクタ->createState() -> initState()->didChangeDependencies()->build()
- initStateはオブジェクト生成時に一度だけ呼ばれる(省略可)
- didChangeDependenciesはinitState直後や依存するオブジェクトが変更されたときに呼ばれる(省略可)
<親ウィジェット更新時>
コンストラクタ->didUpdateWidget()->build()
- didUpdateWidgetは親ウィジェットが新しい設定で再ビルドされ、自身にその状態が引き継がれた時に呼ばれる(省略可)
- 古いStateと新しいStateを比較したい時に利用
<状態更新時>
setState() -> build()
- 画面を更新したい時、setStateを呼び出す。(setStateの定義は省略可)
<ウィジェット消滅時>
dispose()
- ウィジェットが破棄される時に一度だけ呼ばれる。リソースの解放などを行う
https://qiita.com/softimo88/items/7df75fd3bf3a80079f2e
こちらからライフサイクルの図を引用
■状態管理を実現するためのアーキテクチャ
状態管理は煩雑なため、大規模開発では以下のアーキテクチャを利用する
- Bloc: Streamを活用したリアクティブな状態管理
- Redux: ActionCreator(ビジネスロジック) -> Action(状態への操作) -> Reducer(状態更新=Store更新)と役割が一方通行で処理を追いやすい
- Provider: 直感的な状態管理
- Riverpod: Providerの強化版