🦔

flutter_hooksのユースケース、これでええんやろか

2022/10/07に公開

Riverpodと併用はしているのですが、flutter_hooksを使う局面が限られている。Reactの実戦経験が不足しているためなのかもと悩んでいる。

主に使用しているのは、このあたりのHooks。

  • useState
  • useTextEditingController
  • useTabController
  • useScrollController
  • useEffect

共通しているのが、こういうユースケース。

  • 当該画面の中で完結する処理やデータ
  • ページ遷移をしたら以前の状態に復元する必要がない
  • disposeを忘れるとダメなやつ

画面をまたいでデータを共有したいケースだと、globalにデータプロバイダーを定義できるRiverpodでよくね、に倒れてしまう。useContextが本家のHooksと違ってグローバルなデータストアとして使うようにデザインされていないので、Widget完結な使い道に倒しがち。

A画面で自分のプロフィールがでていて、そこからB画面に遷移して、遷移した先で課金をして石が増えるとしよう。A画面に戻った時、プロフに表示済みの石の数は課金反映済のため増えている必要がある。御存知の通り、戻ったときにはA画面のinitStateは走らない。

こういうケースが結構あって、Riverpodの場合だとbuild関数で ref.watch(someProvider)としていれば、someProviderのstateを更新するだけで良い。flutter_hooksでは、この種の用途に向かないと感じる。

よく、TextEditingControllerの解放漏れとか見かけるけど、あれってStatefulWidget特有の話題でええんかな。disposeされる対象はスクリーンにいるWidgetのstateオブジェクト。ウイジェットが破棄されているのに、リスナーが登録されているのはどうなのよでdisposeするって話はわかる。

StateオブジェクトがミュータブルなのがStatefulWidgetで、イミュータブルなのがStatelessWidgetと考えるとわかりやすいな。だとすると、StatelessWidgetがdisposeに該当する処理を書かなくてもよいのもわかる。イミュータブルだから不変なんでしょっていう。

Stream系のdispose処理は、StatefulWidgetでやってもいいけど、ConsumerWidget + autoDisposeがシャレオツなのではないか、とも思う。Widgetのstateがミュータブルになっている画面、オンボーディング完了後のHome画面ぐらい。ここは、その時によってinitStateでハンドリングしたい処理がまぁまぁある。

Discussion