Back to results for “Fundamentals”
Flutter › Flutter Riverpod Code Generation & Providers

How does ref.watch differ from ref.read within a Riverpod provider or widget, and why does correctly and consistently choosing the genuinely appropriate one actually matter quite a lot for overall correct app behavior?

Intermediate

Answer

ref.watch actively subscribes the calling widget or provider to future updates, meaning it will automatically properly rebuild or genuinely recompute again whenever that specific watched provider's own value actually changes, whereas ref.read simply reads the provider's own current value just once at that exact specific moment without establishing any kind of genuine ongoing subscription whatsoever, and using ref.read instead of ref.watch within a widget's own actual build method is a genuinely common and quite easy mistake to make, since it can cause your interface to incorrectly fail to properly update when the underlying watched data actually and genuinely changes.
// In a build method, correctly use watch to properly react to changes
final count = ref.watch(counterProvider);

// In a button's onPressed callback, correctly use read since we only need the current value once
ref.read(counterProvider.notifier).state++;
Real-world example A developer debugging a screen that mysteriously and confusingly fails to properly update discovers they had accidentally used ref.read instead of the genuinely correct ref.watch directly within their widget's own build method, correctly fixing the underlying issue once they properly understood this important key distinction.

Common follow-ups: When would you actually genuinely want to use ref.listen instead of either watch or read?;What happens internally if you accidentally call ref.watch from somewhere outside of an actual provider or a widget's own build method?