NotifierPropiderから AsyncNotifierへと移行したい!

2023/01/25に公開

移行しようと思ったきっかけ

FirebaseやRiverpodを使用したアプリを作っていた際に参考にしていたYoutube[1]で使用しているStateNotifier<AsyncValue>はこれから減っていくのではという記事を見つけ、ではどんなやり方がこれから主流になっていくのかが気になりさわってみたかった。
https://github.com/rrousselGit/riverpod/issues/1712#issuecomment-1264961836

AsyncNotifierとは

AsyncNofierは非同期で初期化を行うことができるNotifierで、例えばネットワークリクエストをキャッチしつつ別の処理を行うことができます。build中にUserを取得しつつ、AsyncNotifierが現在のユーザー名を変更できるsetNameメソッドを公開することができます。

A Notifier implementation that is asynchronously initialized.
Caching a network request while also allowing to perform side-effects. For example, build could fetch information about the current "user". And the AsyncNotifier could expose methods such as "setName", to allow changing the current user name.

プロパティとしてrefAsyncValueを持っている。
特にrefはStaneNotifierと違ってStateNotifierProviderから渡してもらう必要がなく使用することができる。

StateNotifier

final incrementProvider = StateNotifierProvider<Increment, int>((){
return Increment();
});

class Increment extends StateNotifier<int> {
 Counter(this._ref) : super(0);

 final Ref _ref;

 void increment() {
   state++;
   _ref.read(counterProvider2.notifier).update((s) => s + state);
 }
}

AsyncNotifier

final testProvider = AsyncNotifierProvider<Test, int>(() {
 return Test();
});

class Test extends AsyncNotifier<int> {
final test = ref.watch(counterProvider.notifier)
//いかに処理
 }

AsyncValue

AsyncValueはFutureやStreamなどの非同期処理で発生する非同期データを安全に操作するのに役立ちます。またAsyncValueを使用することで非同期操作のloading/error状態を忘れずに簡単にハンドリングできるクラスです。
https://zenn.dev/tsuruo/articles/52f62fc78df6d5#when・whenornull・maybewhen

移行してどうなったか

まずrefに関係する処理がなくなったことで冗長なコードがなくなり、簡潔に書くことができた。
効果を実感するにはまだ自分には経験が足りないので、一回ここまで。

自分が引っかかったところ

mountedがない

廃棄サイクルが違うらしい。(詳しくはいかに)
https://github.com/rrousselGit/riverpod/issues/1908

AsyncLoading と AsyncValue.loadingの違いはなんなのか

AsyncLoading and AsyncValue.loading

以下記事でのの回答を見ると全く同じものだそうです。
https://stackoverflow.com/questions/75079067/asyncloading-vs-asyncvalue-loading

common.dart
 /// Creates an [AsyncValue] in loading state.
  ///
  /// Prefer always using this constructor with the `const` keyword.
  // coverage:ignore-start
  const factory AsyncValue.loading() = AsyncLoading<T>;
  // coverage:ignore-end

注釈

参考

https://zenn.dev/takewoy/scraps/b6e957d899d92f
https://github.com/rrousselGit/riverpod/issues/1767
https://github.com/MarcusNg/flutter_shopping_list/blob/main/lib/controllers/item_list_controller.dart
https://codewithandrea.com/articles/flutter-riverpod-async-notifier/
https://zenn.dev/riscait/books/flutter-riverpod-practical-introduction/viewer/migrate-to-v1#future%2Fstreamprovider-(asyncvalue)-についての変更点-(dev.8~)

脚注
  1. https://www.youtube.com/watch?v=vrPk6LB9bjo&t=1054s ↩︎

Discussion