flutter_riverpod 3.2.0
flutter_riverpod: ^3.2.0 copied to clipboard
A reactive caching and data-binding framework. Riverpod makes working with asynchronous code a breeze.
3.2.0 - 2026-01-17 #
- Fix the IDE pausing on "markNeedsBuild" exceptions when checking "pause on all exceptions".
ConsumerWidget's now uses the TickerMode notifier instead of TickerMode.of to avoid unnecessary rebuilds when widgets are hidden (thanks to @Colton127)- Added missing
weakflags toWidgetRef.listen/listenManual - Added
Ref.isPausedto check if there are any active/non-paused listeners. - Deprecated
family.overrideWithin favour offamily.overrideWith2The behaviour is the same, but the callback now takes the argument as a parameter. In 4.0.0,overrideWith2will be renamed tooverrideWith. - Fix a regression that caused Notifiers to lose their state when one of their dependencies changed. (thanks to @yegair)
- Fixed
ref.mountedreturningtruefor stale refs after provider rebuild, causing race conditions in async providers. - Fixed a bug where providers with only weak listeners (
ref.listen(..., weak: true)) would incorrectly initialize during hot reload (thanks to @tguerin) - Fixes
selectAsyncsometimes throwing an exception when unsubscribed to.
Dependency changes #
riverpodupgraded to3.2.0
3.1.0 - 2025-12-26 #
-
Added an alternative way to combine asynchronous providers. This can be done by using
AsyncValue.requireValueinsideFutureProvider/AsyncNotifierlike so:final sumProvider = FutureProvider((ref) { // Not async AsyncValue<int> a = ref.watch(aProvider); AsyncValue<int> b = ref.watch(bProvider); // The following is safe if used inside the init function of providers. return a.requireValue + b.requireValue; })This enables synchronously combining asynchronous providers.
-
Fixed a bug with scoping when specifying
dependencies: [...] -
Added
Override.origin. This enables knowing which provider is associated with an override. -
Fix a regression with
AsyncLoading.isRefreshing/isReloading
3.0.3 - 2025-10-09 #
riverpodupgraded to3.0.3
3.0.2 - 2025-10-07 #
Fixed an assertion error when a ProviderContainer is linked to two different UncontrolledProviderScope
3.0.1 - 2025-09-30 #
ChangeNotifierProviderFamilyis now correctly accessible inpackage:flutter_riverpod/legacy.dartinstead of/misc.dart- Now supports Dart 3.7.0
3.0.0 - 2025-09-10 #
Finally, a stable release for Riverpod 3.0!
For the full changelog, check out https://riverpod.dev/docs/whats_new
3.0.0-dev.18 - 2025-09-09 #
- A provider that is currently being retried is now flagged as "loading"
while the retry attempts complete.
Meaning that
ref.watch(provider.future)skips the intermediate error states. - Fix an issue with the internals of AsyncValue
ProviderObserveris now marked withbase- Fix provider rebuild order issue.
- Fix "Tried to refresh x multiple times in the same frame" incorrectly triggering.
- Removed
FamilyNotifierand variants, in favour ofNotifier. - Preserve persisted state if a provider throws.
provider.futurewill now skip offline-persisted state by default. This avoids awkward unexpected provider rebuild when chaining persisted providers.- Made
Mutation.callgeneric. This allows for better compatibility with generic-returning functions (thanks to @TekExplorer)
3.0.0-dev.17 - 2025-08-01 #
- Added
MutationState.isPending/isIdle/hasError/isSuccess - fixes various "pause" issues
- Bump minimum
metaversion - Added
AsyncValue.retrying, to check when a retry is scheduled or pending - Exposed the default retry implementation (
ProviderContainer.defaultRetry) - Offline's Storage now is
baseand requires overridingdeleteOutOfDate - Make AsyncValue.copyWithPrevious
@internal. This API was not meant to be public.
3.0.0-dev.16 - 2025-06-20 #
- Reworked mutations to work without code-generation
- Added
Async/SyncProviderTransformerMixin. Those enable making customProviderListenables using a reasonably simple syntax. For instance, you could implement your ownprovider.select - Added
AsyncResult. This is an interface shared betweenAsyncDataandAsyncError, but notAsyncLoading. - Revert Notifier life-cycle change. They are once again preserved across rebuilds.
- Provider errors are now reported to the
ProviderContainer'sZoneinstead of whatever last used the provider. - Breaking: When a
ref.watch/ref.readrethrows an error, the error is now wrapped in aProviderException. - Use TickerMode instead of Visibility for pausing out-of-view widgets
- Reworked offline to simplify its usage
- Added widget test helper to find a
ProviderContainerin the widget tree:tester.container()(thanks to @Luckey-Elijah)
3.0.0-dev.15 - 2025-05-04 #
riverpodupgraded to3.0.0-dev.15
3.0.0-dev.14 - 2025-05-02 #
riverpodupgraded to3.0.0-dev.14
3.0.0-dev.13 - 2025-05-01 #
riverpodupgraded to3.0.0-dev.13
3.0.0-dev.12 - 2025-04-30 #
Say hello to Riverpod 3.0.0! This major version is a transition version, to unblock the development of the project. It is quite possible that a 4.0.0 will be released relatively soon in the future, so keep that in mind when migrating.
Here are some highlights about this version:
- Offline and mutation support, as experimental features
- Automatic retry support
- Pause/resume support
- Simplification of various aspects of the API (such as fusing
AutoDisposeNotifier/Notifier) - Added a
Ref.mountedto simplify dealing with provider disposal - Improved testing with the new
ProviderContainer.test()and the ability to mock a Notifier'sbuildmethod without mocking the whole object usingprovider.overrideWithBuild(...)
Note about experimental features:
Anything imported with package:riverpod/experimental/....dart are not stable features.
They may be modified in breaking ways without a major version. Use with care!
Full change list #
- Breaking:
ChangeNotifierProvider,StateProviderandStateNotifierProviderare moved out ofpackage:hooks_riverpod/hooks_riverpod.darttopackage:hooks_riverpod/legacy.dart. - Failing providers are now automatically retried after a delay. The delay can be optionally configured.
- Allow using Ref synchronously after a provider has been invalidated. This avoids mounted exceptions when doing multiple operations in a quick succession.
- Breaking: All providers now use
==to compare previous/new values and filter updates. If you want to revert to the old behavior, you can overrideupdateShouldNotifyinside Notifiers. - Instead of
Provider.autoDispose()andProvider.autoDispose.family(), it is now possible to writeProvider(isAutoDispose: true)andProvider.family(isAutoDispose: true). - Breaking: ProviderListenable.addListener is deleted and now internal-only. A simpler alternative will be added in the future.
- Breaking: ProviderObserver methods have been updated to take a
ProviderObserverContextparameter. This replaces the oldprovider+containerparameters, and contains extra information. - Breaking: Removed all
Refsubclasses (suchFutureProviderRef). UseRefdirectly instead. ForFutureProviderRef.future, migrate to using anAsyncNotifier. - Breaking All ref and notifier methods besides "mounted" now throw if used after getting disposed.
- Breaking:
StateProviderandStateNotifierProviderare moved out ofpackage:flutter_riverpod/flutter_riverpod.darttopackage:flutter_riverpod/legacy.dart. - Breaking Some internal utils are no-longer exported.
- Breaking
AsyncValue.valuenow returnsnullduring errors. - Breaking removed
AsyncValue.valueOrNull(use.valueinstead). Stream/FutureProvider.overrideWithValuewas added back.- Breaking:
Notifierand variants are now recreated whenever the provider rebuilds. This enables usingRef.mountedto check dispose. - Breaking:
StreamProvidernow pauses itsStreamSubscriptionwhen the provider is not actively listened. - Breaking: Calling ref.watch multiple times calls ref.onListen every-times.
- Breaking: A provider is now considered "paused" if all
of its listeners are also paused. So if a provider
Ais watched only by a providerB, andBis currently unused, thenAwill be paused. - Breaking: When an asynchronous provider rebuilds, it doesn't immediately stops listening to its previous providers. Instead, those subscriptions are removed when the rebuild completes. This impacts how "auto-dispose" behaves. See https://github.com/rrousselGit/riverpod/issues/1253
- Fix
StreamProvidernot cancelling theStreamSubscriptionif the stream is never emitted any value. - All
Reflife-cycles (such asRef.onDispose) andNotifier.listenSelfnow return a function to remove the listener. - Added methods to
ProviderObserverfor listening to "mutations". Mutations are a new code-generation-only feature. See riverpod_generator's changelog for more information. - Added
Ref.listen(..., weak: true). When specifyingweak: true, the listener will not cause the provider to be initialized. This is useful when wanting to react to changes to a provider, but not trigger a network request if not necessary. AsyncValuenow has an optionalprogressfield. This can be set by providers to allow the UI to show a custom progress logic.- An error is now thrown when trying to override a provider twice in the same
ProviderContainer. - Disposing a
ProviderContainernow disposes of all of its subProviderContainerstoo. - Added
ProviderSubscription.pause()/.resume(). This enables temporarily stopping the subscription to a provider, without it possibly loosing its state when usingautoDispose. - Added
ProviderContainer.test(). This is a custom constructor for testing purpose. It is meant to replace thecreateContainerutility. - Added
NotifierProvider.overrideWithBuild, to overrideNotifier.buildwithout overriding methods of the notifier. Ref.mountedhas been added. It can now be used to check if a provider was disposed.- When a provider is rebuilt, a new
Refis now created. This avoids issues where an old build of a provider is still performing work. - Updated
AsyncValuedocumentations to use pattern matching. - Added support for
Ref/ProviderContainer.invalidate(provider, asReload: true) - Failing providers are now automatically retried after a delay. The delay can be optionally configured.
- Fixed a bug when overriding a specific provider of a
family, combined withdependencies: [family]
2.6.1 - 2024-10-22 #
- Added
AsyncNotifier.listenSelf. It was mistakenly absent from the 2.6.0 release
2.6.0 - 2024-10-20 #
- Deprecated all
Refsubclasses. Instead, useRefitself. - Deprecated
Ref's type argument. UseRefwithout its generic parameter instead. - Deprecated any
Refmember that usedRef's generic (such asRef.stateorRef.listenSelf). Instead, use aNotifier. - Added
Notifier.listenSelf, as a replacement toRef.listenSelf. Ref.watchand other methods now accept auto-dispose providers too.
2.5.3 - 2024-10-12 #
- Fixed a typo in the documentation (thanks to @ljbkusters)
2.5.2 - 2024-03-18 #
- Fixed various typos in the documentation (thanks to @kevalvavaliya)
2.5.1 - 2024-03-10 #
- Deprecate
ProviderScope.parentdue to fundamentally not working. See https://github.com/rrousselGit/riverpod/issues/3261 - Improved
Provider(dependencies: [...])documentation. - Fix out of date
pub.devdescription ref.invalidatenow correctly clear all resources associated with the provider if the provider is no-longer used.- Fix
selectAsyncsometimes never resolving. - Fix
ProviderSubscription.readreturned byref.listen(provider.future)not throwing if used after the subscription has been closed. - Fix
ref.onAddListenerand other life-cycles not being triggered when listening toprovider.future/provider.notifier. - Fix a bug that caused
Assertion failed: _lastFuture == null
2.4.10 - 2024-02-03 #
- Fix out of date
pub.devdescription - Add
testargument toAsyncValue.guardmethod. (thanks to @utamori)
2.4.9 - 2023-11-27 #
- Fix "pending timer" issue inside tests when using
ref.keepAlive(). - Fix
Ref.invalidate/Ref.refreshnot throwing on circular dependency. - Fix an infinite loop caused by
ref.keepAliveif theKeepAliveLinkis immediately closed. - Fix
container.exists(provider)on nested containers not checking their parent containers.
2.4.8 - 2023-11-20 #
Fix exceptions when using multiple root ProviderContainers/ProviderScopes.
2.4.7 - 2023-11-20 #
- Fix
ProviderObserver.didUpdateProviderbeing called with an incorrect "provider" parameter when the provider is overridden.
2.4.6 - 2023-11-13 #
- Exceptions in asynchronous providers are now correctly received
by
ProviderObserver.providerDidFail. - Fix exception when a
ProviderScopeis rebuilt with a differentkey.
2.4.5 - 2023-10-28 #
- Support assigning
AsyncValue<T>toAsyncNotifier<void>.state
2.4.4 - 2023-10-15 #
riverpodupgraded to2.4.4
2.4.3 - 2023-10-06 #
- Fixed incorrect
@visibleForTestingwarning.
2.4.2 - 2023-10-02 #
- Improved the error message when WidgetRef is used after the associated widget got unmounted.
2.4.1 - 2023-09-27 #
riverpodupgraded to2.4.1
2.4.0 - 2023-09-04 #
riverpodupgraded to2.4.0
2.3.10 - 2023-08-28 #
riverpodupgraded to2.3.10
2.3.9 - 2023-08-28 #
- Fix some exceptions causing Flutter asking to demangle stacktraces (#1874)
- Fix out of date
AsyncValuedocs.
2.3.7 - 2023-08-16 #
- Added support for state_notifier 1.0.0
Notifier.stateis now accessible inside tests
2.3.6 - 2023-04-24 #
- Improved error message for missing
dependencies(thanks to @ValentinVignal) - Fixed various typos in the documentation (thanks to @ValentinVignal)
- Fix not disposing autoDispose family providers
- Removed incorrect statement in ChangeNotifierProvider docs
2.3.5 - 2023-04-18 #
- fix
AsyncValue.isReloadingdocs
2.3.4 - 2023-04-07 #
- Fixes an issue with nested ProviderScope (thanks to @jeiea)
2.3.3 - 2023-04-06 #
- The debugger no-longer pauses on uncaught exceptions inside providers. This was voluntary, but too many people have complained that it often is a false positive.
- Removed unused dependency (thanks to @passsy)
2.3.2 - 2023-03-13 #
- Deprecated the generic parameter of
Family. This will enable implementing generic providers inriverpod_generatoronce it is removed. - Updated documentation
2.3.1 - 2023-03-09 #
riverpodupgraded to2.3.1
2.3.0 #
-
Added
StreamNotifier+StreamNotifierProvider. This is for building aStreamProviderwhile exposing ways to modify the stream.It is primarily meant to be used using code-generation via riverpod_generator, by writing:
@riverpod class Example extends _$Example { @override Stream<Model> build() { // TODO return some stream } } -
Deprecated
StreamProvider.streamInstead of:ref.watch(provider.stream).listen(...)do:
ref.listen(provider, (_, value) {...});Instead of:
final a = StreamProvider((ref) { return ref.watch(b.stream).map((e) => Model(e)); })Do:
final a = FutureProvider((ref) async { final e = await ref.watch(b.future); return Model(e); }) -
Some restrictions on the
dependenciesparameter of providers have been lifted. It is no-longer necessary to include providers which do not themselves specifydependencies. All providers should specifydependenciesif they are scoped at any point. -
Annotated
Notifier.statesetter as protected.
2.2.0 #
- Improve type-inference when using
AsyncValue.whenOrNull(thanks to @AhmedLSayed9) - Fixed AsyncValue.asError incorrectly not preserving the generic type
- Internal refactoring for riverpod_generator
2.1.3 #
Fixes an issue with FutureProvider<void> (#2028)
2.1.2 #
- It is now correctly possible to use
ProviderSubscriptions insideConsumerState.dispose(thanks to @1980) - Update dependencies.
- fixes an exception on newer Dart versions
- fixes an edge-case where
FutureProvider/AsyncNotifierdid not emit the new state when the createdFuturecompleted (#1997) - fixes errors inside FutureProvider/AsyncNotifier/StreamProvider not preserving the previous state (if any).
- Update dependencies.
2.1.1 #
Fix typos
2.1.0 #
A small release adding missing utilities and fixing some web related issues.
-
Added
provider.overrideWith((ref) => state) -
Added
FutureProviderRef.future. -
Deprecated
StateProvider.stateInstead, use eitherref.watch(stateProvider)orref.read(stateProvider.notifier).state = -
Deprecated
provider.overrideWithProvider. Instead useprovider.overrideWith -
Added
Ref.notifyListeners()to forcibly notify dependents. This can be useful for mutable state. -
Added
@useResulttoRef.refresh/WidgetRef.refresh -
Added
Ref.existsto check whether a provider is initialized or not. -
FutureProvider,StreamProviderandAsyncNotifierProvidernow preserve the previous data/error when going back to loading. This is done by allowingAsyncLoadingto optionally contain a value/error. -
Added
AsyncValue.when(skipLoadingOnReload: bool, skipLoadingOnRefresh: bool, skipError: bool)flags to give fine control over whether the UI should showloadingordata/errorcases. -
Add
AsyncValue.requireValue, to forcibly obtain thevalueand throw if in loading/error state -
Doing
ref.watch(futureProvider.future)can no-longer return aSynchronousFuture. That behavior could break variousFutureutilities, such asFuture.wait -
Add
AsyncValue.copyWithPrevious(..., isRefresh: false)to differentiate rebuilds fromref.watchvs rebuilds fromref.refresh. -
ProviderContainer no-longer throws when disposed if it has an undisposed child ProviderContainer.
-
Improved the error message when trying to modify a provider inside a widget life-cycle.
-
Fixes a stackoverflow on Web caused by Dart (thanks to @leehack)
-
Fixes a bug when the root ProviderContainer is not associated with a ProviderScope.
-
Fixes a case where a circular dependency between providers was incorrectly allowed (#1766)
2.0.2 #
- FIX: Fixed an assert error if a
familydepends on itself while specifyingdependencies. (#1721).
2.0.2 #
Fixed an assert error if a family depends on itself while specifying dependencies.
2.0.1 #
Updated changelog (see 2.0.0)
2.0.0 #
Here is the changelog for all the changes in the 2.0 version. An article is in progress and will be linked here once available.
Breaking changes:
FutureProvider.streamis removed.- Using
overrideWithProvider, it is no-longer possible to override a provider with a different type of provider (such as overridingFutureProviderwith aStreamProvider). AsyncError.stackTraceis now a required positional parameter and non-nullable- All
overrideWithValuemethods are removed, besidesProvider.overrideWithValue. This change is temporary, and these methods will be reintroduced in a later version. In the meantime, you can useoverrideWithProvider. - Modifiers (
provider.future,provider.state, ...) no-longer are providers, and therefore no-longer appear insideProviderObserver. - The
Readertypedef is removed. UseRefinstead. ProviderListeneris removed. Usedref.listeninstead.- Removed the deprecated
ProviderReference. - Providers no-longer throw a
ProviderExceptionif an exception was thrown while building their value. Instead, they will rethrow the thrown exception and its stacktrace. - It is no longer possible to pass
provider.future/.notifier/...to the parameterdependenciesof provider. Passing the provider directly is enough. - The
Familytype now has a single generic parameter instead of 3.
Non-breaking changes:
- Upgrade minimum required Flutter SDK version to 3.0.0
- Upgrade minimum required Dart SDK version to 2.17.0
- Added
WidgetRef.context. This allows functions that depend on aWidgetRefto use theBuildContextwithout having to receive it as parameter. - Added
provider.selectAsync, which allows to both await an async value while also filtering rebuilds. - Added
WidgetRef.listenManualfor listening to providers in a widget outside ofbuild. - Added
ref.listenSelf, for subscribing to changes of a provider within that provider. That can be useful for logging purposes or storing the state of a provider in a DB. - Added
container.invalidate(provider)/ref.invalidate(provider)andref.invalidateSelf(). These are similar toref.refreshmethods, but do not immediately rebuild the provider.
These methods are safer than ref.refresh as they can avoid a provider
rebuilding twice in a quick succession.
-
Added
ref.onAddListener,ref.onRemoveListener,ref.onCancelandref.onResume. All of which allow performing side-effects when providers are listened or stop being listened. -
A new
AutoDisposeRef.keepAlive()function is added. It is meant to replaceAutoDisposeRef.maintainStateto make logic for preventing the disposal of a provider more reusable. -
feat;
AutoDisposeRef.maintainStateis deprecated. Use the newAutoDisposeRef.keepAlive()instead. -
Add support for
ref.invalidate(family)to recompute an entire family (#1517) -
Added
AsyncValue.valueOrNullto obtain the value while ignoring potential errors. -
Added new functionalities to
AsyncValue:hasError,hasData,asError,isLoading,copyWithPreviousandunwrapPrevious.
Fixes:
- fixed a bug where
AsyncValue.whenDatadid not preserveAsyncValue.isLoading/isRefreshing StateProviderandStateNotifierProviderno longer notify their listeners onref.refreshif the new result is identical to the old one.- fixed potential null exception when using
autoDispose - fixed a bug where unmounting a nested ProviderScope could cause an exception (#1400)
- Fixed an issue where providers were incorrectly allowed to depend on themselves,
breaking
autoDisposein the process. - Fixed a memory leak when using
StateProvider.autoDispose's.state - Fix
ProviderObserver.didDisposeProvidernot executing on provider refresh. - Fixed an issue where
AsyncValue.valuedid not throw if there is an error. - Fixed a cast error when overriding a provider with a more specific provider type (#1100)
- Fixed a bug where
onDisposelisteners could be executed twice under certain conditions when usingautoDispose. - Fixed an issue where refreshing a
provider.future/provider.streamdid work properly - Fixed false positive with
ref.watchasserts
1.0.3 #
Removed an assert preventing from overriding the same provider/family
multiple times on a ProviderScope/ProviderContainer.
1.0.2 #
Fixed a null exception on web
1.0.1 #
Improved the performance of the assert which verifies that providers properly
respect their dependencies variable.
1.0.0 #
Riverpod is now stable!
General changes #
-
Breaking:
ProviderContainer.debugProviderValuesandProviderContainer.debugProviderElementsare removed. You can now instead useProviderContainer.getAllProviderElements. -
ChangeNotifierProvidernow supports nullableChangeNotifier(#856) -
Increased minimum SDK version to 2.14.0
-
Breaking The return value when reading a
StateProviderchanged. Before, doingref.read(someStateProvider)would return theStateControllerinstance. Now, this will only return the state of theStateController. This new behavior matchesStateNotifierProvider.For a simple migration, the old behavior is available by writing
ref.read(someStateProvider.state). -
Added
ref.listenfor triggering actions inside providers/widgets when a provider changes.It can be used to listen to another provider without recreating the provider state:
final counterProvider = StateNotifierProvider<Counter, int>(...); final anotherProvider = Provider<T>((ref) { ref.listen<int>(counterProvider, (previous, count) { print('counter changed from $previous to $count'); }); });Alternatively, it can be used by widgets to show modals/dialogs:
final counterProvider = StateNotifierProvider<Counter, int>(...); class Example extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { ref.listen<int>(counterProvider, (previous, count) { showDialog(...); }); } } -
ProviderListeneris deprecated in favor ofref.listen. -
It is now possible to "await" all providers that emit an
AsyncValue(previously limited toFutureProvider/StreamProvider). This includes cases where aStateNotifierProviderexposes anAsyncValue:class MyAsyncStateNotifier extends StateNotifier<AsyncValue<MyState>> { MyAsyncStateNotifier(): super(AsyncValue.loading()) { // TODO fetch some data and update the state when it is obtained } } final myAsyncStateNotifierProvider = StateNotifierProvider<MyAsyncStateNotifier, AsyncValue<MyState>>((ref) { return MyAsyncStateNotifier(); }); final someFutureProvider = FutureProvider((ref) async { MyState myState = await ref.watch(myAsyncStateNotifierProvider.future); }); -
Deprecated
StreamProvider.lastin favor ofStreamProvider.future. -
StreamProvider.future,StreamProvider.streamandFutureProvider.futurenow expose a future/stream that is independent from how many times the associated provider "rebuilt":- if a
StreamProviderrebuild before its stream emitted any value,StreamProvider.futurewill resolve with the first value of the new stream instead. - if a
FutureProviderrebuild before its future completes,FutureProvider.futurewill resolve with the result of the new future instead.
- if a
-
You can now override any provider with any other provider, as long as the value that they expose matches. For example, it is possible to override a
StreamProvider<Model>with aProvider<AsyncValue<Model>>. -
ref.onDisposenow calls the dispose function as soon as one of the provider's dependency is known to have changed -
Providers can now call
ref.refreshto refresh a provider, instead of having to doref.container.refresh. -
Providers no longer wait until their next read to recompute their state if one of their dependency changed and they have listeners.
-
Added
ProviderContainer.pump, a utility to easily "await" until providers notify their listeners or are disposed. -
fixed an issue when using both
familyandautoDisposethat could lead to an inconsistent state
Unified the syntax for interacting with providers #
-
Breaking: The prototype of
ConsumerWidget'sbuildandConsumer'sbuilderchanged. Before:class Example extends ConsumerWidget { @override Widget build(BuildContext context, ScopedReader watch) { int count = watch(counterProvider); ... } }After:
class Example extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { int count = ref.watch(counterProvider); ... } } -
ProviderListeneris deprecated. Instead, useref.listen:class Example extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { ref.listen<int>(counter, (count) { print('count changed $count'); }); } } -
Added
ConsumerStatefulWidget+ConsumerState, a variant ofStatefulWidgets that have access to aWidgetRef. -
All "watch" functions now support
myProvider.select((value) => ...). This allows filtering rebuilds:final userProvider = StateNotifierProvider<UserController, User>(...); Consumer( builder: (context, ref, _) { // With this syntax, the Consumer will not rebuild if `userProvider` // emits a new User but its "name" didn't change. bool userName = ref.watch(userProvider.select((user) => user.name)); }, ) -
ProviderReferenceis deprecated in favor ofRef. -
Breaking:
ProviderObserver.didUpdateProvidernow receives both the previous and new value. -
Breaking:
ProviderObserver.mayHaveChangedis removed. -
Breaking:
Family.overrideWithProvidernow must create a provider:final family = Provider.family<State, Arg>(...); family.overrideWithProvider( (Arg arg) => Provider<State>((ref) => ...) ); -
All providers now receive a custom subclass of
ProviderRefBaseas a parameter:Provider<T>((ProviderRef<T> ref) {...}); FutureProvider<T>((FutureProviderRef<T> ref) {...}); StateProvider<T>((StateProviderRef<T> ref) {...});That allows providers to implement features that is not shared with other providers.
-
Provider,FutureProviderandStreamProvider'srefnow have astateproperty, which represents the currently exposed value. Modifying it will notify the listeners:Provider<int>((ref) { ref.listen(onIncrementProvider, (_) { ref.state++; }); return 0; }); -
StateProvider'srefnow has acontrollerproperty, which allows the provider to access theStateControllerexposed.
-
-
Breaking:
ProviderReference.mountedis removed. You can implement something similar usingonDispose:Provider<T>((ref) { var mounted = true; ref.onDispose(() => mounted = false); });
All providers can now be scoped. #
-
Breaking:
ScopedProvideris removed. To migrate, changeScopedProviders toProviders. -
All providers now come with an extra named parameter called
dependencies. This parameter optionally allows defining the list of providers/families that this new provider depends on:final a = Provider(...); final b = Provider((ref) => ref.watch(a), dependencies: [a]);By doing so, this will tell Riverpod to automatically override
bifagets overridden.
Updated AsyncValue: #
-
Breaking
AsyncValue.copyWithis removed -
Breaking
AsyncValue.error(..., stacktrace)is now a named parameter instead of positional parameter. -
Deprecated
AsyncValue.datain favor ofAsyncValue.value -
Allowed
AsyncData,AsyncErrorandAsyncLoadingto be extended -
Added
AsyncValue.whenOrNull, similar towhenOrElsebut instead of an "orElse" parameter, returnsnull. -
Added
AsyncValue.value, which allows reading the value without handling loading/error states. -
AsyncErrorcan now be instantiated withconst. -
Added
StateController.update, to simplify updating the state from the previous state:final provider = StateController((ref) => 0); ... ref.read(provider).update((state) => state + 1); -
It is no longer allowed to use
ref.watchorref.readinside a selector:provider.select((value) => ref.watch(something)); // KO, cannot user ref.watch inside selectors -
FutureProvider now creates a
FutureOr<T>instead of aFuture<T>. That allows bypassing the loading state in the event where a value was synchronously available.
Bug fixes #
- Fixed a bug where widgets were not rebuilding in release mode under certain conditions
- FIX: StreamProvider.last no longer throws a StateError when no value were emitted (#296).
- fixed an issue where when chaining providers, widgets may re-render a frame late, potentially causing a flicker. (see #648)
1.0.0-dev.11 #
Fixed an issue where dependencies did not work for ChangeNotifierProvider (#800)
1.0.0-dev.10 #
Fixed a bug where reading a provider within a consumer could throw (#796)
1.0.0-dev.9 #
Fix an issue where *Provider.autoDispose were not able to specify the
dependencies parameter.
1.0.0-dev.8 #
Future/StreamProvider #
-
FutureProvider now creates a
FutureOr<T>instead of aFuture<T>That allows bypassing the loading state in the event where a value was synchronously available. -
During loading and error states,
FutureProviderandStreamProvidernow expose the latest value throughAsyncValue. That allows UI to show the previous data while some new data is loading, instead of showing a spinner:final provider = FutureProvider<User>((ref) async { ref.watch(anotherProvider); // may cause `provider` to rebuild return fetchSomething(); }) ... Widget build(context, ref) { return ref.watch(provider).when( error: (err, stack, _) => Text('error'), data: (user) => Text('Hello ${user.name}'), loading: (previous) { if (previous is AsyncData<User>) { return Text('loading ... (previous: ${previous.value.name})'); } return CircularProgressIndicator(); } ); }
AsyncValue #
- Breaking
AsyncValue.copyWithis removed - Breaking
AsyncValue.error(..., stacktrace)is now a named parameter instead of positional parameter. - Breaking
AsyncValue.when(loading: )andAsyncValue.when(error: )(andwhenvariants) now receive an extra "previous" parameter. - Deprecated
AsyncValue.datain favor ofAsyncValue.value - Allowed
AsyncData,AsyncErrorandAsyncLoadingto be extended - Added
AsyncValue.whenOrNull, similar towhenOrElsebut instead of an "orElse" parameter, returnsnull. - Added
AsyncValue.value, which allows reading the value without handling loading/error states. AsyncErrorcan now be instantiated withconst.AsyncLoadingandAsyncErrornow optionally includes the previous state.
General #
-
Breaking All
overrideWithProvidermethods are removed. To migrate, instead useoverrideWithValue. -
All providers now come with an extra named parameter called
dependencies. This parameter optionally allows defining the list of providers/families that this new provider depends on:final a = Provider(...); final b = Provider((ref) => ref.watch(a), dependencies: [a]);By doing so, this will tell Riverpod to automatically override
bifagets overridden. -
Added
StateController.update, to simplify updating the state from the previous state:final provider = StateController((ref) => 0); ... ref.read(provider).update((state) => state + 1); -
It is no longer allowed to use
ref.watchorref.readinside a selector:provider.select((value) => ref.watch(something)); // KO, cannot user ref.watch inside selectors
Bug-fixes #
- fixed a bug where providers were rebuilding even when not listened to
- fixed
ref.listennow working when downcasing the value of a provider. - fixed a bug where disposing a scoped
ProviderContainercould cause otherProviderContainers to stop working. - fixed an issue where conditionally depending on an "autoDispose" provider may not properly dispose of it (see #712)
- fixed an issue where when chaining providers, widgets may re-render a frame late, potentially causing a flicker. (see #648)
1.0.0-dev.7 #
- Fixed
ProviderObservernot working when modifying aStateProvider. - Fixed a bug where scoped provider were potentially not disposed
- Fixed a bug where widgets were not rebuilding in release mode under certain conditions
1.0.0-dev.6 #
- FIX: StreamProvider.last no longer throws a StateError when no value were emitted (#296).
- Re-enabled debug assertions that were temporarily disabled by previous dev versions.
- Allows families to be scoped/overridden
- Fixed bugs with
ref.refreshnot working on some providers - renamed
ProviderBase.recreateShouldNotifytoupdateShouldNotify
1.0.0-dev.5 #
Fixed an issue where provider listeners could not be called properly.
1.0.0-dev.3 #
Fixed various issues related to scoped providers.
1.0.0-dev.2 #
- All providers can now be scoped.
- breaking:
ScopedProvideris removed. To migrate, changeScopedProviders toProviders.
1.0.0-dev.1 #
- Add missing exports (see #532)
1.0.0-dev.0 #
-
Breaking: The prototype of
ConsumerWidget'sbuildandConsumer'sbuilderchanged. Before:class Example extends ConsumerWidget { @override Widget build(BuildContext context, ScopedReader watch) { int count = watch(counterProvider); ... } }After:
class Example extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { int count = ref.watch(counterProvider); ... } } -
ProviderListeneris deprecated. Instead, useref.listen:class Example extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { ref.listen<int>(counter, (count) { print('count changed $count'); }); } } -
Added
ConsumerStatefulWidget+ConsumerState, a variant ofStatefulWidgets that have access to aWidgetRef. -
All "watch" functions now support
myProvider.select((value) => ...). This allows filtering rebuilds:final userProvider = StateNotifierProvider<UserController, User>(...); Consumer( builder: (context, ref, _) { // With this syntax, the Consumer will not rebuild if `userProvider` // emits a new User but its "name" didn't change. bool userName = ref.watch(userProvider.select((user) => user.name)); }, ) -
Breaking:
Family.overrideWithProvidernow must create a provider:final family = Provider.family<State, Arg>(...); family.overrideWithProvider( (Arg arg) => Provider<State>((ref) => ...) ); -
Breaking:
ProviderObserver.didUpdateProvidernow receives both the previous and new value. -
Breaking:
ProviderObserver.mayHaveChangedis removed. -
Added
ref.listen, used to listen to another provider without recreating the provider state:final counter = StateNotifierProvider<Counter, int>(...); final anotherProvider = Provider<T>((ref) { ref.listen<int>(counter, (count) { print('counter change: $count'); }); }); -
ProviderReferenceis deprecated in favor ofProviderRefBase. -
All providers now receive a custom subclass of
ProviderRefBaseas a parameter:Provider<T>((ProviderRef<T> ref) {...}); FutureProvider<T>((FutureProviderRef<T> ref) {...}); StateProvider<T>((StateProviderRef<T> ref) {...});That allows providers to implement features that is not shared with other providers.
-
Provider,FutureProviderandStreamProvider'srefnow have astateproperty, which represents the currently exposed value. Modifying it will notify the listeners:Provider<int>((ref) { ref.listen(onIncrementProvider, (_) { ref.state++; }); return 0; }); -
StateProvider'srefnow has acontrollerproperty, which allows the provider to access theStateControllerexposed.
-
-
Breaking:
ProviderReference.mountedis removed. You can implement something similar usingonDispose:Provider<T>((ref) { var mounted = true; ref.onDispose(() => mounted = false); }); -
Breaking:
ProviderContainer.debugProviderValuesandProviderContainer.debugProviderElementsare removed. You can now instead useProviderContainer.getAllProviderElements. -
StreamProvider.last,StreamProvider.streamandFutureProvider.futurenow expose a future/stream that is independent from how many times the associated provider "rebuilt":- if a
StreamProviderrebuild before its stream emitted any value,StreamProvider.lastwill resolve with the first value of the new stream instead. - if a
FutureProviderrebuild before its future completes,FutureProvider.futurewill resolve with the result of the new future instead.
- if a
-
You can now override any provider with any other provider, as long as the value that they expose matches. For example, it is possible to override a
StreamProvider<Model>with aProvider<AsyncValue<Model>>. -
Providers can now call
ref.refreshto refresh a provider, instead of having to doref.container.refresh. -
ref.onDisposenow calls the dispose function as soon as one of the provider's dependency is known to have changed -
Providers no longer wait until their next read to recompute their state if one of their dependency changed and they have listeners.
-
Added
ProviderContainer.pump, a utility to easily "await" until providers notify their listeners or are disposed. -
fixed an issue when using both
familyandautoDisposethat could lead to an inconsistent state
0.14.0+3 #
Removed an assert that could cause issues when an application is partially migrated to null safety.
0.14.0+2 #
- Fix
context.refreshnot compiling when using nullable providers
0.14.0+1 #
- Re-added
StateProvider.overrideWithValue/StateProvider.overrideWithProviderthat were involuntarily removed.
0.14.0 #
-
BREAKING CHANGE The
Listener/LocatorMixintypedefs are removed as the former could cause a name conflict with the widget namedListenerand the latter is not supported when using Riverpod. -
BREAKING CHANGE The syntax for using
StateNotifierProviderwas updated. Before:class MyStateNotifier extends StateNotifier<MyModel> {...} final provider = StateNotifierProvider<MyStateNotifier>((ref) => MyStateNotifier()); ... Widget build(context, watch) { MyStateNotifier notifier = watch(provider); MyModel model = watch(provider.state); }After:
class MyStateNotifier extends StateNotifier<MyModel> {...} final provider = StateNotifierProvider<MyStateNotifier, MyModel>>((ref) => MyStateNotifier()); ... Widget build(context, watch) { MyStateNotifier notifier = watch(provider.notifier); MyModel model = watch(provider); }See also https://github.com/rrousselGit/riverpod/issues/341 for more information.
-
BREAKING CHANGE It is no longer possible to override
StreamProvider.stream/lastandFutureProvider.future. -
feat: Calling
ProviderContainer.disposemultiple time no longer throws. This simplifies the tear-off logic of tests. -
feat: Added
ChangeNotifierProvider.notifierandStateProvider.notifierThey allow obtaining the notifier associated with the provider, without causing widgets/providers to rebuild when the state updates. -
fix: overriding a
StateNotifierProvider/ChangeNotifierProviderwithoverrideWithValuenow correctly listens to the notifier.
0.13.1+1 #
Fixed an issue where context.read and ProviderListener were unable to read providers that return a nullable value
0.13.1 #
- Fixed a bug where overriding a
FutureProviderwith an error value could cause tests to fail (see https://github.com/rrousselGit/riverpod/issues/355)
0.13.0 #
- stable null-safety release
ProviderObservercan now have a const constructor- Added the mechanism for state-inspection using the Flutter devtool
- loosened the version constraints of
freezed_annotation - deprecated
import 'flutter_riverpod/all.dart'. Now everything is available withflutter_riverpod/flutter_riverpod.dart. - Fixed a but where listening to
StreamProvider.lastcould result in aStateError(#217) - removed the assert preventing ConsumerWidget's "watch" from being used after the
buildmethod completed. This allows "watch" to be used insideListView.builder. context.read(myProvider)now acceptsScopeProviders
0.13.0-nullsafety.3 #
- deprecated
import 'flutter_riverpod/all.dart'. Now everything is available withflutter_riverpod/flutter_riverpod.dart. - removed the assert preventing ConsumerWidget's "watch" from being used after the
buildmethod completed. This allows "watch" to be used insideListView.builder. context.read(myProvider)now acceptsScopeProviders
0.13.0-nullsafety.2 #
- Fixed outdated doc
0.13.0-nullsafety.1 #
- Fixed a but where listening to
StreamProvider.lastcould result in aStateError(#217)
0.13.0-nullsafety.0 #
Migrated to null-safety
0.12.2 #
- Exported
AutoDisposeProviderRefBase
0.12.1 #
- Fixed an remaining memory leak related to StreamProvider (see also https://github.com/rrousselGit/riverpod/issues/193)
0.12.0 #
- Breaking FutureProvider and StreamProvider no longer supports
nullas a valid value. - Fixed a memory leak with StreamProvider (see also https://github.com/rrousselGit/riverpod/issues/193)
- Fixed an error message typo related to Consumer
0.11.2 #
- Fixed a bug where providers (usually ScopedProviders) did not dispose correctly (see also https://github.com/rrousselGit/riverpod/issues/154).
0.11.1 #
- Fixed a bug where hot-reload did not work for
ConsumerWidget/Consumer
0.11.0 #
package:flutter_riverpod/flutter_riverpod.dartnow exportsStateNotifier- Marked the providers with
@sealedso that the IDE warns against implementing/subclassing providers. - Fix mistakes in
AsyncValue.guard's documentation (thanks @mono0926) - Loosened the version constraints of
freezed_annotationto support0.12.0
0.10.1 #
- Fixed invalid version error
0.10.0 #
-
Fixed a bug where the state of a provider may be disposed when it shouldn't be disposed.
-
Added a way to import the implementation class of providers with modifiers, such as
AutoDisposeProvider.This is useful if you want to use Riverpod with the lint
always_specify_types:import 'package:flutter_riverpod/all.dart'; final AutoDisposeStateProvider<int> counter = StateProvider.autoDispose<int>((ProviderRefBase ref) { return 0; });If you do not use this lint, prefer using the default import instead, to not pollute your auto-complete.
0.9.0 #
- Breaking Updating
ProviderListenerso thatonChangereceives theBuildContextas a parameter (thanks to @tbm98)
0.8.0 #
- Renamed
ProviderContainer.debugProviderStatestoProviderContainer.debugProviderElements - Fixed a bug where updating
ProviderScope.overridesmay cause an exception for no reason (see https://github.com/rrousselGit/riverpod/issues/107)
0.7.2 #
Fixed a bug that prevented the use of ConsumerWidget under normal circumstances
0.7.1 #
- Fixed a bug where in release mode,
ScopedProviderdid not update correctly (https://github.com/rrousselGit/riverpod/issues/101)
0.7.0 #
-
Breaking:
Consumeris slightly modified to match other Builders likeValueListenableBuilder. Before:return Consumer((context, watch) { final value = watch(myProvider); return Text('$value'); });after:
return Consumer( builder: (context, watch, child) { final value = watch(myProvider); return Text('$value'); }, ); -
Added a
ConsumerWidgetclass which can be extended to make aStatelessWidgetthat can read providers:class MyWidget extends ConsumerWidget { const MyWidget({Key? key}) : super(key: key); @override Widget build(BuildContext context, ScopedReader watch) { final value = watch(myProvider); return Text('$value'); } } -
ref.watchon non ".autoDispose" providers can no longer read ".autoDispose" providers.For more info, see http://riverpod.dev/docs/concepts/modifiers/auto_dispose#the-argument-type-autodisposeprovider-cant-be-assigned-to-the-parameter-type-alwaysaliveproviderbase
-
ScopedProvidernow acceptsnullas a function:final example = ScopedProvider<int>(null);Which is equivalent to:
final example = ScopedProvider<int>((watch) => throw UnimplementedError('')); -
Fixed a bug where
context.refreshmay not work properly if the widget tree contains multipleProviderScope.
0.6.1 #
- Fixed a bug where when disposing
ProviderContainer, providers may be disposed in an incorrect order. - Improved the performances of reading providers by 25%
0.6.0 #
-
Merged
ComputedandProvider. Now, all providers have the ability to rebuild their state when one of the object they listen changed.To migrate, change:
final provider = Provider(...); final example = Computed((watch) { final value = watch(provider); return value; });into:
final provider = Provider(...); final example = Provider((ref) { final value = ref.watch(provider); return value; }); -
Computed(nowProvider) no longer deeply compare collections to avoid rebuilds. Comparing the content of lists is quite expensive and actually rarely useful. Now, a simple==comparison is used. -
Renamed
ProviderStateOwnertoProviderContainer -
Renamed
ProviderStateOwnerObservertoProviderObserver -
It is no longer possible to override a provider anywhere in the widget tree. Providers can only be overridden in the top-most
ProviderScope/ProviderContainer. -
Providers can now read values which may change over time using
ref.readandref.watch. When usingref.watch, if the value obtained changes, this will cause the provider to re-create its state. -
It is no longer possible to add
ProviderObserveranywhere in the widget tree. They can be added only on the top-mostProviderScope/ProviderContainer. -
Provider.read(BuildContext)is changed intocontext.read(provider), and can now readProvider.autoDispose. -
Added
ProviderContainer.refresh(provider)andcontext.refresh(provider). These method allows forcing the refresh of a provider, which can be useful for things like "retry on error" or "pull to refresh".
-
ref.read(StreamProvider<T>)no longer returns aStream<T>but anAsyncValue<T>Before:final streamProvider = StreamProvider<T>(...); final example = Provider((ref) { Stream<T> stream = ref.read(streamProvider); });After:
final streamProvider = StreamProvider<T>(...); final example = Provider((ref) { Stream<T> stream = ref.watch(streamProvider.steam); }); -
ref.read(FutureProvider<T>)no longer returns aFuture<T>but anAsyncValue<T>Before:
final futureProvider = FutureProvider<T>(...); final example = Provider((ref) { Future<T> future = ref.read(futureProvider); });After:
final futureProvider = FutureProvider<T>(...); final example = Provider((ref) { Future<T> future = ref.watch(futureProvider.future); }); -
Removed
ref.dependOn. You can now useref.read/ref.watchto achieve the same effect.Before:
final streamProvider = StreamProvider<T>(...); final example = Provider((ref) { Future<T> last = ref.dependOn(streamProvider).last; });After:
final streamProvider = StreamProvider<T>(...); final example = Provider((ref) { Future<T> last = ref.watch(streamProvider.last); }); -
Provider.readOwner(ProviderStateOwner)is changed intoProviderContainer.read(Provider) -
Provider.watchOwner(ProviderStateOwner, (value) {})is changed into:ProviderContainer container; final provider = Provider((ref) => 0); final subscription = container.listen( provider, mayHaveChanged: (sub) {}, didChange: (sub) {}. ); subscription.close(); -
MyProvider.family.autoDisposenow correctly free both the arguments and the associated providers from memory when the provider is no longer listened to.
-
Added
ScopedProvider, a new kind of provider that can be overridden anywhere in the widget tree. Normal providers cannot read aScopedProvider. -
Added
ProviderListener, a widget which allows listening to a provider without rebuilding the widget-tree. This can be useful for showing modals and pushing routes.
0.5.1 #
- Fixed the documentation of
StateNotifierProviderincorrectly showing the documentation ofStreamProvider. - Improve the documentation of
StateProvider.
0.5.0 #
- Changed
ComputedFamilyintoComputed.family - Added [AsyncValue.guard](https://pub.dev/documentation/riverpod/latest/riverpod/AsyncValue/guard.html to simplify transforming a Future into an AsyncValue.
- Improved the documentation of the different providers
0.4.0 #
Changed the syntax of "AutoDispose*" and "*Family" to use a syntax similar to named constructors instead.
Before:
final myProvider = AutoDisposeStateNotifierProviderFamily<MyStateNotifier, int>((ref, id) {
return MyStateNotifier(id: id);
});
After:
final myProvider = StateNotifierProvider.autoDispose.family<MyStateNotifier, int>((ref, id) {
return MyStateNotifier(id: id);
});
The behavior is the same. Only the syntax changed.
0.3.0 #
-
Added
AsyncValue.whenData, syntax sugar forAsyncValue.whento handle only thedatacase and do nothing for the error/loading cases. -
Fixed a bug that caused [Computed] to crash if it stopped being listened to then was listened to again.
0.2.1 #
ComputedandConsumernow correctly unsubscribe to a provider when their function stops using a provider.
0.2.0 #
ref.readis renamed asref.dependOn- Deprecated
ref.dependOn(streamProvider).streamandref.dependOn(futureProvider).futurein favor of a universalref.dependOn(provider).value. - added
ref.read(provider), syntax sugar forref.dependOn(provider).value.
0.1.0 #
Initial release