DEV3 Technologies home

DEV3 Developer Forum

In Riverpod, when should I use ref.watch, ref.read and ref.listen?

Flutter helpSolved0 views
dev3 ·

I keep mixing ref.watch and ref.read and sometimes get a warning or a screen that never updates. What is the rule for each, and where is it safe to call them?

#flutter#riverpod#state

0

1 reply

dev3 · Accepted answer

The rule

  • ref.watch(provider): use in build (and inside other providers). It returns the value and rebuilds the widget or provider whenever the value changes.
  • ref.read(provider): use in callbacks (onPressed, onTap, initState-like code). It reads once, never subscribes.
  • ref.listen(provider, (prev, next) {...}): use for side effects that are not UI, such as showing a SnackBar, navigating or logging when state changes.
class LoginButton extends ConsumerWidget {
  const LoginButton({super.key});
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final state = ref.watch(loginControllerProvider);

    ref.listen(loginControllerProvider, (prev, next) {
      if (next.hasError) {
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text('${next.error}')));
      }
    });

    return FilledButton(
      onPressed: state.isLoading
          ? null
          : () => ref.read(loginControllerProvider.notifier).submit(),
      child: const Text('Sign in'),
    );
  }
}

Why not read in build

ref.read in build gives a stale snapshot: the widget will not update when the provider changes. It looks fine until the first state change.

Why not watch in callbacks

Watching in an event handler is flagged (it is not a valid place for a subscription) and is wasted work.

Inside a Notifier

In build() of a Notifier/AsyncNotifier use ref.watch for dependencies you want to react to. In its other methods use ref.read.

Reduce rebuilds

ref.watch(userProvider.select((u) => u.name)) rebuilds only when name changes.

Pitfall

Never call ref.read to get a value you then store in a field of a long-lived object, it will not follow later changes.

0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.