Here is a very curious case with Riverpod which is probably a bug.
The existence of a simple watch
line prevents a listen
from executing. When watch
ing a base provider and listen
ing to a provider that depends on it, listen
only executes if you do not watch
the base.
Here are the providers:
final baseProvider = Provider<int>(
(ref) => 0,
);
final dependentProvider = Provider<String>(
(ref) {
final q = ref.watch(baseProvider);
return '$q';
},
dependencies: [baseProvider],
);
Here is the code that overrides it:
class _MainPageState extends State<MainPage> {
var overridingValue = 1;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ProviderScope(
overrides: [
baseProvider.overrideWithValue(overridingValue),
],
child: const MyConsumer(),
),
ElevatedButton(
onPressed: () {
setState(() {++overridingValue;});
},
child: const Text('increment'),
),
],
),
),
);
}
}
And here's the code under that override that exhibits the curious behavior. Simply uncommenting the ref.watch
line prevents the ref.listen
from firing.
class MyConsumer extends ConsumerWidget {
const MyConsumer({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
// the print line in listen below is executed only when this line is commented out
// If you uncomment this line, the print line is not executed anymore.
//
// final q = ref.watch(baseProvider);
ref.listen(
dependentProvider,
(previous, next) {
print('Listened to $previous -> $next');
},
);
return const SizedBox.shrink();
}
}
This difference in behavior resulting from a harmless .watch() is really curious. Is there an explanation on why this may be happening? Is this a bug?
Please find a repo here that demonstrates this behavior: https://github.com/gazialankus/riverpod_query_play The stateprovider_instead_of_scope
branch there shows that this only happens with a ProviderScope override.
And here is a DartPad for an easy experience: https://dartpad.dev/?id=3aefed6429499de5a939a6c50d158534