flutterdartriverpod

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:


Solution

  • 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.