Minimal reproducible code:
class FooPage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final asyncValue = ref.watch(sp);
print('loading = ${asyncValue.isLoading}, value = ${asyncValue.valueOrNull}');
return Container();
}
}
final sp = StreamProvider<int>((ref) async* {
yield 0;
});
Output:
flutter: loading = true, value = null
flutter: loading = false, value = 0
flutter: loading = false, value = 0
What called it, or why the line flutter: loading = false, value = 0
is repeated two times?
CodePudding user response:
It looks like the ConsumerWidget is being rebuilt twice, which causes the StreamProvider to be rebuilt as well. This is why you're seeing the StreamProvider being called multiple times.
One way to fix this issue would be to wrap the ConsumerWidget in a Memoized widget, which will prevent the ConsumerWidget from being rebuilt unnecessarily.
Here's an example of how you could do that:
class FooPage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final asyncValue = ref.watch(sp);
print('loading = ${asyncValue.isLoading}, value = ${asyncValue.valueOrNull}');
return Container();
}
}
final sp = StreamProvider<int>((ref) async* {
yield 0;
});
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Memoized(
child: FooPage(),
);
}
}
This will prevent the ConsumerWidget from being rebuilt, which in turn will prevent the StreamProvider from being called multiple times.