Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Riverpod ref.read() vs ref.listen() vs ref.watch()

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:

  • What is the purpose and difference between these functions?
  • Where and where not can I use these functions?
  • When should I use these functions?
like image 579
Vraj Shah Avatar asked Sep 06 '25 03:09

Vraj Shah


1 Answers

What is the purpose and difference between these functions?

read()

Use read to the get the value of/in a provider just once (one-time read)

watch()

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()

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)

Where and where not can I use these functions?

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.

When should I use these functions?

read()

Use read when you want to get the value of the provider only once.

watch()

Use watch when you want to always get the value.

Example: Counter app with 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.

  • We're watching the counter value so it gets updated in the UI anytime there is a change.
  • We're listening to the counter to print the updated value and print I've reached 5 when it is 5.
  • To increment the value, we read the provider state and add 1 when the FloatingActionButton is pressed.
like image 136
Josteve Avatar answered Sep 07 '25 23:09

Josteve