select<Selected> method
Partially listen to a provider.
Note: This method of listening to an object is currently only supported
by useProvider
from hooks_riverpod
and ProviderContainer.listen.
The select function allows filtering unwanted rebuilds of a Widget by reading only the properties that we care about.
For example, consider the following ChangeNotifier
:
class Person extends ChangeNotifier {
int _age = 0;
int get age => _age;
set age(int age) {
_age = age;
notifyListeners();
}
String _name = '';
String get name => _name;
set name(String name) {
_name = name;
notifyListeners();
}
}
final personProvider = ChangeNotifierProvider((_) => Person());
In this class, both name
and age
may change, but a widget may need
only age
.
If we used useProvider
/Consumer
as we normally would, this would cause
widgets that only use age
to still rebuild when name
changes, which
is inefficient.
The method select can be used to fix this, by explicitly reading only a specific part of the object.
A typical usage would be:
@override
Widget build(BuildContext context, ScopedReader watch) {
final age = useProvider(personProvider.select((p) => p.age));
return Text('$age');
}
This will cause our widget to rebuild only when age
changes.
NOTE: The function passed to select can return complex computations too.
For example, instead of age
, we could return a "isAdult" boolean:
@override
Widget build(BuildContext context, ScopedReader watch) {
final isAdult = useProvider(personProvider.select((p) => p.age >= 18));
return Text('$isAdult');
}
This will further optimise our widget by rebuilding it only when "isAdult" changed instead of whenever the age changes.
Implementation
ProviderListenable<Selected> select<Selected>(
Selected Function(Listened value) selector,
) {
return ProviderSelector<Listened, Selected>(
provider: this,
selector: selector,
);
}