💡
Riverpodでfamilyプロバイダの全キャッシュをinvalidateする
概要
flutterの状態管理ライブラリであるRiverpodに関するTipsです。通常familyなプロバイダは引数ごとにinvalidateしてキャッシュを失効させることしかできませんが、全てのキャッシュをまとめて失効させたいことがあったので方法を考えてみました。
どういうこと?
まずは何がしたいのかを説明。
記事IDに対する記事内容を取得するarticleProvider
があったとして。コードは次のような感じになると思います。
final articleProvider =
FutureProvider.family<Article, int>((ref, articleId) async {
final service = HogeService();
return await service.getArticle(articleId);
});
ここで特定の記事IDに対する内容を再度取得させるには保持しているキャッシュを削除する必要があります。そんな場合は次のようにinvalidate
することでキャッシュが削除され、次回要求時に再度articleProvider
の中の処理が実行されます。
ref.invalidate(articleProvider(記事ID));
特定記事に関してはこのコードでよいのですが、「全ての記事に対してキャッシュ削除したいんだよね」という場合があったとき・・そんな話です。イメージ的に↓こういうこと↓がしたいイメージ。
ref.invalidate(articleProvider(全ての記事ID));
方法
family全引数に対するキャッシュをinvalidate...というのはできませんので、リフレッシュ用のキーを用意してやります。
final articleRefreshKeyProvider = StateProvider<int>((ref) => 0);
で、このリフレッシュキーをarticleProvider
でwatchします。要するに依存させるわけです。
final articleProvider =
FutureProvider.family<Article, int>((ref, articleId) async {
final refreshKey = ref.watch(articleRefreshKeyProvider); // watchする
final service = HogeService();
return await service.getArticle(articleId);
});
キャッシュを全て削除したい場合は次のようにステートを更新してやります。これで使用中のarticleProvider
は全てキャッシュを削除することになります。
ref.read(articleRefreshKeyProvider.notifier).state++;
おわりに
というわけで目的は果たせたのですが、Riverpod初心者なのでこれでいいのかやや不安・・・。もっといい方法あったら教えてほしいです。
Discussion