RiverpodのProviderが管理するStateに引数を与えて初期化したい
画面遷移とかでよくあるよね。一覧から行タップで詳細に遷移する系のやつ。商品一覧→商品詳細みたいなやつです。
Riverpodが提供するProviderにはfamily
という関数があり、Providerを初期化する際に任意の型の引数を与えることができる。今回は、StateNotifierProviderでありながら、autoDispose
もfamily
も使うというこんもりセットだった。
// 第1引数: 利用するStateNotifierの型 // 第2引数: 第1引数に入れたStateNotifierで管理するStateの型 // 第3引数: 管理するStateの初期化に必要なパラメータの型 final calcProvider = AutoDisposeStateNotifierProviderFamily<CartPageStateNotifier, Cart, Cart>( (ref, param) => CartPageStateNotifier.init(cart: param)); //Widget内部ではこうなる。ConsumerWidgetを使っています。 //このitemは画面遷移でもらったデータで Widget hogeWidget(BuildContext context, ScopedReader watch) { final state = watch(calcProvider(item)); final vm = watch(calcProvider(item).notifier); }
class CartPageStateNotifier extends StateNotifier<Cart> { CartPageStateNotifier() : super(const Cart()); CartPageStateNotifier.init({required Cart cart}) : super(cart); }
こんな感じで、CartPageStateNotifier
に名前付きのコンストラクタを定義しておく。init
は渡したいデータでstate
を初期化する際に呼び出す。
RiverPodの設計思想は勉強になるなぁ.. というか、型がある言語はナイスだなぁ... PythonもTypeHintあるけどね。おほほンゴ。