Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unhandled Exception: setState() or markNeedsBuild() called during build. when combining overrides and async providers #3498

Open
ValentinVignal opened this issue Apr 19, 2024 · 0 comments
Assignees
Labels
bug Something isn't working
Milestone

Comments

@ValentinVignal
Copy link
Contributor

Describe the bug

I'm using flutter_riverpod: ^2.5.1

I'm having the error Unhandled Exception: setState() or markNeedsBuild() called during build. when I combine overriddes and async providers (StreamProvider or FutureProvider).

To Reproduce

Run flutter run on the code sample:

Code sample
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

void main() {
  runApp(
    const ProviderScope(
      child: MyApp(),
    ),
  );
}

class MyApp extends ConsumerWidget {
  const MyApp({
    super.key,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return MaterialApp(
      home: ProviderScope(
        overrides: [
          parameterProvider.overrideWithValue(null),
        ],
        child: const Scaffold(
          body: Column(
            children: [
              Widget1(),
              Widget2(),
            ],
          ),
        ),
      ),
    );
  }
}

class Widget1 extends ConsumerWidget {
  const Widget1({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final version = ref.watch(combinedProvider) != null;

    return Text('version $version');
  }
}

class Widget2 extends ConsumerWidget {
  const Widget2({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final combined = ref.watch(combinedProvider) != null;
    final provider = ref.watch(secondProvider) != null;
    return Text('notifier $provider, combined $combined');
  }
}

final parameterProvider = Provider.autoDispose<int?>((ref) => null);

final futureProvider = FutureProvider.autoDispose<int>((ref) async {
  return 42;
});

final secondProvider = Provider.autoDispose<int?>((ref) {
  return ref.watch(futureProvider).valueOrNull;
}, dependencies: [futureProvider]);

final combinedProvider = Provider.autoDispose<int?>(
  (ref) {
    return ref.watch(parameterProvider) ?? ref.watch(secondProvider);
  },
  dependencies: [parameterProvider, secondProvider],
);
Logs
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: setState() or markNeedsBuild() called during build.
This Widget1 widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was:
  Widget1
The widget which was currently being built when the offending call was made was:
  Widget2
#0      Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:5033:9)
#1      Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:5045:6)
#2      ConsumerStatefulElement.watch.<anonymous closure>.<anonymous closure> (package:flutter_riverpod/src/consumer.dart:566:20)
#3      ProviderBase.addListener.<anonymous closure> (package:riverpod/src/framework/provider_base.dart:98:41)
#4      _RootZone.runBinaryGuarded (dart:async/zone.dart:1606:10)
#5      ProviderElementBase._notifyListeners.<anonymous closure> (package:riverpod/src/framework/element.dart:525:28)
#6      ResultData.map (package:riverpod/src/result.dart:74:16)
#7      ProviderElementBase._notifyListeners (package:riverpod/src/framework/element.dart:519:14)
#8      ProviderElementBase._performBuild (package:riverpod/src/framework/element.dart:358:7)
#9      ProviderElementBase.flush (package:riverpod/src/framework/element.dart:307:7)
#10     ProviderElementBase.readSelf (package:riverpod/src/framework/element.dart:776:5)
#11     _ProviderStateSubscription.read (package:riverpod/src/framework/provider_base.dart:181:28)
#12     ConsumerStatefulElement.watch (package:flutter_riverpod/src/consumer.dart:568:8)
#13     Widget2.build (package:flutter_app_stable/main.dart:53:26)
#14     _ConsumerState.build (package:flutter_riverpod/src/consumer.dart:476:19)
#15     StatefulElement.build (package:flutter/src/widgets/framework.dart:5583:27)
#16     ConsumerStatefulElement.build (package:flutter_riverpod/src/consumer.dart:539:20)
#17     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5471:15)
#18     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5634:11)
#19     Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7)
#20     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2895:19)
#21     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:984:21)
#22     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:457:5)
#23     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1325:15)
#24     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1255:9)
#25     SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:978:7)
#26     Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
#27     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
#28     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5)
#29     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

Expected behavior
A clear and concise description of what you expected to happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants