タイトルの通り、今更ながらRiverPodのdependenciesを試してみたメモです。
※RiverPod 1.0.3で確認
そもそもdependenciesとは?
https://pub.dev/documentation/riverpod/latest/riverpod/Provider/dependencies.html
かんたんにいうと、ProviderRefからScopedなProviderにアクセスするためのパラメータです。dependenciesにScopedなProviderを指定すると、そのProviderもScopedになりアクセスが可能になります。
final scopedValue = Provider((_) => '1');
final valueDependsOnScopedValue = Provider(
(ref) => ref.watch(scopedValue),
// この指定により、scopedValueがoverrideされるとvalueDependsOnScopedValueもscopedになる
dependencies: [scopedValue],
);
触ってイメージを掴みたい方はDartPadがあるので試してみてください。
https://dartpad.dev/?id=f8c9ce39572deed30dc47ed754c1c170
注意点
基本的には便利なdependenciesですが、触っていて下記の2点に気をつける必要がありそうだなとおもいました。
- dependenciesを指定したら、ScopedでないProviderに依存する場合そのProviderを指定しないとExceptionを投げられる
- overridesされたらdependenciesを指定しないとExceptionを投げられる
- .futureで呼んでいるFutureProviderは.futureでdependenciesする必要がある
一つづつ見てみましょう。
dependenciesを指定したら、ScopedでないProviderに依存する場合そのProviderを指定しないとExceptionを投げられる
例として、こんなコードがあります。
final scopedValue = Provider((_) => '1');
final valueNonAddedScopedValueToDependencies = Provider(
(ref) => ref.watch(scopedValue),
);
この場合、dependencies指定していないからoverrideしても1が返ってくるのかな?と思いますが、overrideすると落ちます。
overridesされるProviderに依存する場合、かならずdependenciesを指定する必要があるようです。
overridesされたらdependenciesを指定しないとExceptionを投げられる
たとえばこんな実装があったとします。
final scopedValue = Provider((_) => '1');
final countState = StateProvider(
(ref) => 0,
);
final _valueDependsOnScopedValue = Provider(
(ref) => '${ref.watch(scopedValue)}${ref.watch(countState)}',
dependencies: [scopedValue],
);
こちらも問題ないように見えますが、これはoverridesされているか否かに関わらず落ちます。
dependenciesを指定する場合は、そのProviderが依存するProviderをすべて指定する必要があるようです。
.futureで呼んでいるFutureProviderは.futureでdependenciesする必要がある
タイトルのとおりです