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

335

What is the purpose and difference between these functions?

read()

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

watch()

Use watch to the get the value of/in 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 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.
Share:
335
Vraj Shah
Author by

Vraj Shah

I am a computer science student just trying my best to learn as much I possibly can about programming and helping others based on my findings.

Updated on January 04, 2023

Comments

  • Vraj Shah
    Vraj Shah over 1 year

    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?
  • Richard
    Richard about 2 years
    Your answer links to the same documentation the question links to, which he just said doesn't explain it very well.
  • Kaan Taha Köken
    Kaan Taha Köken almost 2 years
    it is not advised to use read inside build method. It is already mentioned in the docs. Also, for the sake of counter-example, instead of using ref.read, it is suggesting different approach.
  • Kaan Taha Köken
    Kaan Taha Köken almost 2 years
    riverpod.dev/docs/concepts/reading checkout the lower section of this page
  • Josteve
    Josteve almost 2 years
    @KaanTahaKöken, ref.read can be called anywhere, while it's not advised - If you have a particular use case (say you only want to read an object just once and you don't want it to get updated) then using it is very fine.
  • Josteve
    Josteve almost 2 years
    For the counter example in the documentation, the example was written using a StateNotifierProvider but it doesn't mean writing the counter app with StateProvider is wrong - In fact, using StateProvider for a simple Counter app (as seen in the example) is more advisable.
  • Kaan Taha Köken
    Kaan Taha Köken almost 2 years
    If you hover over ref.read it gives the exact use case. Using ref.read especially inside ConsumerWidget's build gave me a lot of headaches. The only use case that I prefer using on onTap/onPressed. Generally, prefer using watch with select
  • Josteve
    Josteve almost 2 years
    I guess you're right, I've updated my answer.