Clean Architecture, Clean Life

仕事・個人での技術的なことつぶやきます

【Flutter】RiverPodでautodispose+readを使う際の注意点

経緯

RiverPodのStateProviderを使う際、stateの監視が不要で、Notifier内で定義している関数を使いたかったので、watchではなく下記のようにreadを使用しました

(コードはダミーです)

Widget build(BuildContext context, WidgetRef ref) {
  return ElevatedButton(
    onTap: () => ref.read(counterProvider.notifier).update(state),
    Navigator.of(context).push(
           MaterialPageRoute(
             builder: (context) =>
                const NextPage(),
           ),
    )
  );
}

しかし、これを実行しても関数が実行されずに画面遷移してしまいました

原因

対象のProvider(ここでいうcounterProvider)でautoDisposeを設定されていたのが原因でした

readで関数を呼び出しているので関数内でstateを更新しても、watchしていないためすぐにstateが破棄されてしまい、stateが更新されていないように見えたということでした

解決策

①readではなくwatch使う

onTap: () => ref.watch(counterProvider.notifier).update(state),

watchにしてもWidgetが頻繁に再描画されたりすることはなく、特に困ることはないので、これが一番安い解決策です

②autoDispose修飾子を外す

【before】

final counterProvider = StateNotifierProvider.autoDispose<int>((ref) => 0);

【after】

final counterProvider = StateNotifierProvider<int>((ref) => 0);

ただ、わざわざref.refresh()追記するくらいならwatchでいいと思います

autoDispose使う際は気を付けたいですね