Skip to content

avoid_ref_read_inside_build

v0.4.0 Warning Fix Riverpod State

This rule flags ref.read() calls that appear directly inside a build() method of a Riverpod consumer widget or state. Since ref.read only fetches the value once and does not subscribe to changes, the widget will not rebuild when the provider updates.

Using ref.read in build() is almost always a mistake. The widget renders with whatever value the provider had at that moment, but never updates when the value changes. This leads to stale UI that does not reflect the current application state. Use ref.watch to subscribe and rebuild automatically. Note that ref.read inside callbacks (like onPressed) is perfectly fine and intentional.

See also: ref.read vs ref.watch

class MyWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
// Reads once, never rebuilds on changes
final value = ref.read(someProvider);
return Text(value);
}
}
class MyWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
// Subscribes and rebuilds when provider changes
final value = ref.watch(someProvider);
return Text(value);
}
}
// ref.read inside a callback is fine
class MyOtherWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
return ElevatedButton(
onPressed: () {
// Intentional one-time read triggered by user action
final value = ref.read(someProvider);
},
child: const Text('Tap'),
);
}
}

To disable this rule:

plugins:
many_lints:
diagnostics:
avoid_ref_read_inside_build: false