1、
extension on AutoDisposeRef {
// When invoked keeps your provider alive for [duration]
void cacheFor(Duration duration) {
final link = keepAlive();
final timer = Timer(duration, () => link.close());
ref.onDispose(() => timer.cancel());
}
}
final myProvider = Provider.autoDispose<int>((ref) {
ref.cacheFor(Duration(minutes: 5));
});
2、 New in Riverpod 2.0: NotifierProvider and AsyncNotifierProvider
https://github.com/bizz84/async_notifier_example_riverpod.git
@riverpod --> family
https://codewithandrea.com/articles/flutter-riverpod-generator/
3、 Disadvantage: Not all provider types are supported yet
Out of the six different kinds of providers, riverpod_generator only supports two of them:
-
Provider
(works with generator) -
StateProvider
(legacy) -
StateNotifierProvider
(legacy) -
FutureProvider
(works with generator) StreamProvider
-
ChangeNotifierProvider
(legacy)
As we will see in the next article, StateProvider
and StateNotifierProvider
can be replaced by the new Notifier
and AsyncNotifier
.
But for now, there isn't a straightforward migration strategy that will work for existing apps. And if your app uses a realtime database and relies heavily on streams, you can't take advantage of the new syntax yet.
4、When to use ref.watch vs ref.read?
As a rule of thumb, we should:
call ref.watch(provider) to observe a provider's state in the build method and rebuild a widget when it changes
call ref.read(provider) to read a provider's state just once (this can be useful in initState or other lifecycle methods)
However, in the code above we have called ref.read(provider.notifier) and used it to modify its state.
The .notifier syntax is available with StateProvider and StateNotifierProvider only and works as follows:
call ref.read(provider.notifier) on a StateProvider<T> to return the underlying StateController<T> that we can use to modify the state
call ref.read(provider.notifier) on a StateNotifierProvider<T> to return the underlying StateNotifier<T> so we can call methods on it
Alongside ref.read and ref.watch, we also have ref.listen
5、## Scoping Providers
With Riverpod, we can scope providers so that they behave differently for a specific part of the application.
这里列举了一个 ListView 性能优化的列子
// 1. Declare a Provider
final currentProductIndex = Provider<int>((_) => throw UnimplementedError());
class ProductList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView.builder(itemBuilder: (context, index) {
// 2. Add a parent ProviderScope
return ProviderScope(
overrides: [
// 3. Add a dependency override on the index
currentProductIndex.overrideWithValue(index),
],
// 4. return a **const** ProductItem with no constructor arguments
child: const ProductItem(),
);
});
}
}
class ProductItem extends ConsumerWidget {
const ProductItem({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
// 5. Access the index via WidgetRef
final index = ref.watch(currentProductIndex);
// do something with the index
}
}