Skip to main content

riverpod

PackageKindProvides the roleNeedsChoose with
smf_riverpodinfrastructureState managementnothing-m riverpod

riverpod manages the state of screens with Riverpod 3, through flutter_riverpod, without code generation.

What it adds to the app​

The module adds flutter_riverpod: ^3.4.3 to the dependencies, and a ProviderScope around the root widget in lib/main.dart:

runApp(ProviderScope(child: const App()));

In the guide for coding agents of the app, the module writes the section "State management". The state of a screen is a NotifierProvider.autoDispose in the directory of its feature, written by hand. The screen is a ConsumerWidget that passes the state on to a view that imports no flutter_riverpod. State that several screens read is a provider without autoDispose. After an await, a Notifier checks ref.mounted before it sets state, and it reads what the call needs from ref before the await. A widget talks only to providers, never to a service or a DI container, and the ProviderScope stays above every widget that reads one.

Features with state​

A feature that keeps state supports Riverpod through a variant keyed by the id of this module, riverpod. The variant brings the providers of the feature's screens. A provider that needs a service of the DI container gets it in the feature's composition file, through a bridge such as Provider<CounterStore>((_) => resolve<CounterStore>()). The variant depends on flutter_riverpod with the constraint any, so the version comes from this module. See Write a feature module.

Among the built-in features, sign_in has such a variant:

  • Each of its screens has a provider in a file next to it, with its Notifier, such as signInProvider in lib/features/sign_in/sign_in_notifier.dart. It is a NotifierProvider.autoDispose, so it lasts as long as its screen. The screen is a ConsumerWidget that watches the provider and gives its view the state. The view is a plain Flutter widget that imports nothing of flutter_riverpod.
  • State that several screens read is a provider without autoDispose. sessionProvider in lib/features/sign_in/session_provider.dart is one, and a widget reads who uses the app with ref.watch(sessionProvider).
  • The notifiers reach the session of the app through appSessionProvider, which a test overrides with a session of its own.
  • A notifier reads what it needs from ref before an await, and checks ref.mounted after it, since the user may have left the screen while the call was on its way.
  • A provider is one for the app, so two pages of one screen that are open at once show the same state.

home, onboarding and settings keep no state in a state manager, so they work the same with riverpod and without it.

The ProviderScope and other wrappers​

The ProviderScope has to be above every widget that reads a provider. Other modules can wrap the root widget too, and their wrappers come in the order of their modules: a module comes after the providers of the roles it requires and after the modules it depends on. A module can use Riverpod only through its variant for riverpod, which makes it require the state management role, or by depending on this module. Either way it comes after riverpod, so its wrapper always goes inside the ProviderScope.

Choosing it​

smf create asks which module manages the state of the app, and offers bloc and None as well. To choose it without the question:

smf create my_app -m riverpod

An app has at most one module that manages its state.