💡

Riverpodでfamilyプロバイダの全キャッシュをinvalidateする

2024/12/17に公開

概要

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