After reading the documentation, it did not explain very well what ref.read()
, ref.watch()
, and ref.listen()
is.
The questions I have are as follows:
Use read
to the get the value of/in a provider just once (one-time read)
Use watch
to the get the value of/in a provider the first time and every time the value changes (see it like you're subscribing to the provider, so you get notified any time there's a change)
listen
is similar to watch
. The main difference is the return type.
watch
returns the new value directly, listen
returns a void
but gives access to the new value and the old value with a callback (See examples below)
You can use read
in places like initState
, callbacks like onPressed
etc. watch
and listen
should not be called asynchronously, like inside an onPressed
of an ElevatedButton. Nor should it be used inside initState
and other State life-cycles.
As Kaan Taha Köken pointed out:
AVOID using [read] for creating widgets with a value that never changes and CONSIDER using [Provider] or
select
for filtering unwanted rebuilds.
Use read
when you want to get the value of the provider only once.
Use watch
when you want to always get the value.
StateProvider
final counterProvider = StateProvider((ref) => 0);
class HomePage extends ConsumerWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final counter = ref.watch(counterProvider);
ref.listen(
counterProvider,
(previous, next) {
print("The new value is $next");
if (next == 5) {
print("I just reached 5");
}
},
);
return Scaffold(
body: Center(
child: Text(
counter.toString(),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
ref.read(counterProvider.state).state += 1;
},
),
);
}
}
The example above shows the use of watch
, read
and listen
.
watch
ing the counter
value so it gets updated in the UI anytime there is a change.listen
ing to the counter
to print the updated value and print I've reached 5
when it is 5.read
the provider state and add 1
when the FloatingActionButton
is pressed.