Iganinのブログ

日頃の開発で学んだ知見を中心に記事を書いています。

【Flutter】RiverpodのProviderの変化を検知する

TL;DR;

  • ProviderObserverを使用し,ProviderScopeのobservers引数に設定する

環境

[] Flutter (Channel stable, 2.2.3, on macOS 11.3.1 20E241 darwin-x64, locale ja-JP)
[] Xcode - develop for iOS and macOS
[] Chrome - develop for the web
[] Android Studio (version 2020.3)
[] IntelliJ IDEA Ultimate Edition (version 2021.1.2)
[] VS Code (version 1.59.1)

hooks_riverpod: 0.14.0+4

ProviderObserver

デバッグ時などにProviderの生成や破棄、値の状態の変化を確認したいことがある。 変なタイミングでDisposeされていないか、逆に適切なタイミングでDisposeされずに残り続けていないかを把握することは意味がある。

Riverpodにはそういった要望に応える仕組みとして、ProviderObserverがある。 ProviderObserverはProviderContainerの状態を監視し、変化をメソッド経由で受け取る。 メソッドは現状4つある。

// providerの追加時に呼ばれる
void didAddProvider(ProviderBase provider, Object? value)
// providerの依存関係変化時に呼ばれる
void mayHaveChanged(ProviderBase provider)
// providerからnotificationが発されたタイミングで呼ばれる
// 依存関係が変化したとしても、valueが変化していない場合は呼ばれない
void didUpdateProvider(ProviderBase provider, Object? newValue)
// providerが破棄されたタイミングで呼ばれる
void didDisposeProvider(ProviderBase provider)

実装

実際の実装は以下のようになる。 ProviderObserverを継承したクラスを作成し、メソッドをoverrideする。 そのクラスをProviderScopeのobservers引数に渡す。

あとは、ProviderObserverを継承したクラスでoverrideしたメソッド内でログメソッドなど好きなメソッドを呼び出せばいい。 なお、各メソッドはデフォルトの処理が定義されているので、必要なメソッドのみoverrideすれば良い。

@immutable
class _ProviderObserver extends ProviderObserver {
  const _ProviderObserver();

  @override
  void didAddProvider(ProviderBase provider, Object? value) {  log method }

  @override
  void didDisposeProvider(ProviderBase provider) { log method   }

  @override
  void didUpdateProvider(ProviderBase provider, Object? newValue) { log method }

  @override
  void mayHaveChanged(ProviderBase provider) { log method  }
}

void main() {
  runApp(
    ProviderScope(
      observers: [
        const _ProviderObserver(),
      ],
      child: App(),
    ),
  );
}

参考