diff --git a/packages/riverpod/CHANGELOG.md b/packages/riverpod/CHANGELOG.md index c5b4ff5ee..8abe0dad8 100644 --- a/packages/riverpod/CHANGELOG.md +++ b/packages/riverpod/CHANGELOG.md @@ -1,5 +1,6 @@ ## Unreleased fix +- Improved `Provider(dependencies: [...])` documentation. - Fix out of date `pub.dev` description ## 2.4.9 - 2023-11-27 diff --git a/packages/riverpod/lib/src/framework/foundation.dart b/packages/riverpod/lib/src/framework/foundation.dart index 73ebb7604..93508c9f2 100644 --- a/packages/riverpod/lib/src/framework/foundation.dart +++ b/packages/riverpod/lib/src/framework/foundation.dart @@ -75,6 +75,11 @@ abstract class ProviderOrFamily implements ProviderListenableOrFamily { /// /// In that scenario, the `dependencies` parameter is required and it must /// include `scopedProvider`. + /// + /// See also: + /// - [provider_dependencies](https://github.com/rrousselGit/riverpod/tree/master/packages/riverpod_lint#provider_dependencies-riverpod_generator-only) + /// and [scoped_providers_should_specify_dependencies](https://github.com/rrousselGit/riverpod/tree/master/packages/riverpod_lint#scoped_providers_should_specify_dependencies-generator-only).\ + /// These are lint rules that will warn about incorrect `dependencies` usages. final Iterable? dependencies; /// All the dependencies of a provider and their dependencies too. diff --git a/packages/riverpod_annotation/CHANGELOG.md b/packages/riverpod_annotation/CHANGELOG.md index bb0534041..6e532261c 100644 --- a/packages/riverpod_annotation/CHANGELOG.md +++ b/packages/riverpod_annotation/CHANGELOG.md @@ -1,3 +1,7 @@ +## Unreleased patch + +- Improved `@Riverpod(dependencies: [...])` documentation. + ## 2.3.3 - 2023-11-27 - `riverpod` upgraded to `2.4.9` diff --git a/packages/riverpod_annotation/lib/src/riverpod_annotation.dart b/packages/riverpod_annotation/lib/src/riverpod_annotation.dart index 4086d1242..6d94a6938 100644 --- a/packages/riverpod_annotation/lib/src/riverpod_annotation.dart +++ b/packages/riverpod_annotation/lib/src/riverpod_annotation.dart @@ -29,10 +29,75 @@ class Riverpod { /// Defaults to false. final bool keepAlive; - /// The list of dependencies of a provider. + /// The list of providers that this provider potentially depends on. /// - /// Values passed to the list of dependency should be the classes/functions - /// annotated with `@riverpod`; not the provider. + /// This list must contains the classes/functions annotated with `@riverpod`, + /// not the generated providers themselves. + /// + /// Specifying this list is strictly equivalent to saying "This provider may + /// be scoped". If a provider is scoped, it should specify [dependencies]. + /// If it is never scoped, it should not specify [dependencies]. + /// + /// The content of [dependencies] should be a list of all the providers that + /// this provider may depend on which can be scoped. + /// + /// For example, consider the following providers: + /// ```dart + /// // By not specifying "dependencies", we are saying that this provider is never scoped + /// @riverpod + /// Foo root(RootRef ref) => Foo(); + /// // By specifying "dependencies" (even if the list is empty), + /// // we are saying that this provider is potentially scoped + /// @Riverpod(dependencies: []) + /// Foo scoped(ScopedRef ref) => Foo(); + /// ``` + /// + /// Then if we were to depend on `rootProvider` in a scoped provider, we + /// could write any of: + /// + /// ```dart + /// @riverpod + /// Object? dependent(DependentRef ref) { + /// ref.watch(rootProvider); + /// // This provider does not depend on any scoped provider, + /// // as such "dependencies" is optional + /// } + /// + /// @Riverpod(dependencies: []) + /// Object? dependent(DependentRef ref) { + /// ref.watch(rootProvider); + /// // This provider decided to specify "dependencies" anyway, marking + /// // "dependentProvider" as possibly scoped. + /// // Since "rootProvider" is never scoped, it doesn't need to be included + /// // in "dependencies". + /// } + /// + /// @Riverpod(dependencies: [root]) + /// Object? dependent(DependentRef ref) { + /// ref.watch(rootProvider); + /// // Including "rootProvider" in "dependencies" is fine too, even though + /// // it is not required. It is a no-op. + /// } + /// ``` + /// + /// However, if we were to depend on `scopedProvider` then our only choice is: + /// + /// ```dart + /// @Riverpod(dependencies: [scoped]) + /// Object? dependent(DependentRef ref) { + /// ref.watch(scopedProvider); + /// // Since "scopedProvider" specifies "dependencies", any provider that + /// // depends on it must also specify "dependencies" and include "scopedProvider". + /// } + /// ``` + /// + /// In that scenario, the `dependencies` parameter is required and it must + /// include `scopedProvider`. + /// + /// See also: + /// - [provider_dependencies](https://github.com/rrousselGit/riverpod/tree/master/packages/riverpod_lint#provider_dependencies-riverpod_generator-only) + /// and [scoped_providers_should_specify_dependencies](https://github.com/rrousselGit/riverpod/tree/master/packages/riverpod_lint#scoped_providers_should_specify_dependencies-generator-only).\ + /// These are lint rules that will warn about incorrect `dependencies` usages. final List? dependencies; }