【Flutter】RivderpodのStateNotifierがoverrideWithProviderできるようになっていた
こんにちは、とりかつ(@torikatsu923)です。
RiverpodでScopedProviderを使わなくてもStateNotifierをoverrideできるようになっていました。 今回はStateNotifierをoverrideする方法について紹介します。
今までのStateNotifier.family
以前以下のような記事を書きました。 torikatsu923.hatenablog.com
この記事では 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と同じように利用できる点がとても便利になりました。