【Flutter】RivderpodのStateNotifierがoverrideWithProviderできるようになっていた
RiverpodでScopedProviderを使わなくてもStateNotifierをoverrideできるようになっていました。
こんにちは、とりかつ(@torikatsu923)です。
RiverpodでScopedProviderを使わなくてもStateNotifierをoverrideできるようになっていました。 今回はStateNotifierをoverrideする方法について紹介します。
今までのStateNotifier.family
以前以下のような記事を書きました。
【riverpod】画面遷移時にStateNotifierへ値を渡す方法 - torikatsu.dev
この記事では StateNotifierFamily を用いてStateNotifierの初期値を設定していました。 そして、初期値を設定したStateNotifierをウィジェットツリーから利用するために以下のようなコードを書く必要がありました。
このコードでやっていることは以下のとおりです。
- StateNotifier.family(
providerFamily)を定義する (最終的にウィジェットツリーから利用したいStateNotifier) - 初期値を設定したproviderFamilyをprovideするめに利用するScopedProvider(
provider)を定義する - ProviderScopeで生成した
providerFamilyを、providerをoverrideすることで子ウィジェットから利用可能にする
provider定義側
final provider =
ScopedProvider<StateNotifierProvider<SomeStateNotifier, SomeState>>(
(ref) => throw Error());
final providerFamily =
StateNotifierProvider.family<SomeStateNotifier, SomeState, String>(
(ref, text) => SomeStateNotifier(text: text));
なんらかのウィジェット
// ...
return ProviderScope(
overrides: [
provider
.overrideAs((watch) => providerFamily(text)),
],
ところがRiverpod 1.0.0で以下のような変更が入っていました。
All providers can now be scoped. Breaking: ScopedProvider is removed. To migrate, change ScopedProviders to Providers.
ScopedProviderが撤廃されて、全てのProviderが overrideWithProvider することが可能になりました。
これによって上と同じことを以下のコードで実現できるようになりました。
provider定義側
final provider = StateNotifierProvider<SomeStateNotifier, SomeState>(
(ref) => throw Error());
final providerFamily =
StateNotifierProvider.family<SomeStateNotifier, SomeState, String>(
(ref, text) => SomeStateNotifier(text: text));
なんらかのウィジェット
// ...
return ProviderScope(
overrides: [
provider.overrideWithProvider(providerFamily("some text")),
],
StateNotifierをoverrideできると嬉しいこと
Providerをoverrideするためのコードは大きく変化しているようには見えません。
では、この変更がどういう時に嬉しいのでしょうか。 この変更はWidgetRef経由でStateNotifierを利用する際にとても便利になります。
従来のScopedProviderを利用する場合は、StateNotifierへアクセスするために以下のようにする必要がありました。
ref.read(ref.read(provider))
ScopedProviderによってprovideされるproviderをread する必要があったため ref.read を二重にしています。大したことないように見えますが、実装を進めていくと毎回二重に ref.read をするのは結構面倒でした。
これがアップデートによって ref.read が一回で済むようになりました。
ref.read(provider)
二重に ref.read する手間を省ける上に、StateNotifier.familyを利用してもStateNotifierと同じように利用できる点がとても便利になりました。
-––