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

This Consumer widget cannot be marked as needing to build because the framework is already in the process of building widgets. #3124

Closed
hcanyz opened this issue Nov 15, 2023 · 3 comments · Fixed by #3117
Assignees
Labels
bug Something isn't working
Milestone

Comments

@hcanyz
Copy link

hcanyz commented Nov 15, 2023

Describe the bug

E/flutter ( 9320): This Consumer 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.
E/flutter ( 9320): The widget on which setState() or markNeedsBuild() was called was:
E/flutter ( 9320):   Consumer
E/flutter ( 9320): The widget which was currently being built when the offending call was made was:
E/flutter ( 9320):   UncontrolledProviderScope
E/flutter ( 9320): #0      Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:4862:9)
E/flutter ( 9320): #1      Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:4874:6)
E/flutter ( 9320): #2      ConsumerStatefulElement.watch.<anonymous closure>.<anonymous closure> (package:flutter_riverpod/src/consumer.dart:569:20)
E/flutter ( 9320): #3      _RootZone.runBinaryGuarded (dart:async/zone.dart:1606:10)
E/flutter ( 9320): #4      ProviderElementBase._notifyListeners.<anonymous closure> (package:riverpod/src/framework/element.dart:537:24)
E/flutter ( 9320): #5      ResultData.map (package:riverpod/src/result.dart:74:16)
E/flutter ( 9320): #6      ProviderElementBase._notifyListeners (package:riverpod/src/framework/element.dart:534:14)
E/flutter ( 9320): #7      ProviderElementBase._performBuild (package:riverpod/src/framework/element.dart:374:7)
E/flutter ( 9320): #8      ProviderElementBase.flush (package:riverpod/src/framework/element.dart:325:7)
E/flutter ( 9320): #9      _ProviderScheduler._performRefresh (package:riverpod/src/framework/scheduler.dart:85:41)
E/flutter ( 9320): #10     _ProviderScheduler._task (package:riverpod/src/framework/scheduler.dart:73:5)
E/flutter ( 9320): #11     vsync.<anonymous closure>.invoke (package:riverpod/src/framework/scheduler.dart:31:13)
E/flutter ( 9320): #12     _UncontrolledProviderScopeElement.build (package:flutter_riverpod/src/framework.dart:390:12)
E/flutter ( 9320): #13     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5297:15)
E/flutter ( 9320): #14     Element.rebuild (package:flutter/src/widgets/framework.dart:5016:7)
E/flutter ( 9320): #15     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2779:19)
E/flutter ( 9320): #16     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:916:21)
E/flutter ( 9320): #17     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:360:5)
E/flutter ( 9320): #18     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1297:15)
E/flutter ( 9320): #19     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1227:9)
E/flutter ( 9320): #20     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1085:5)
E/flutter ( 9320): #21     _invoke (dart:ui/hooks.dart:170:13)
E/flutter ( 9320): #22     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:401:5)
E/flutter ( 9320): #23     _drawFrame (dart:ui/hooks.dart:140:31)

To Reproduce

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'main.g.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        ),
        body: const Column(
          children: [ShowDataWidget(), ShowDataWidget()],
        ),
      ),
    );
  }
}

@Riverpod(dependencies: [])
String initData(InitDataRef ref) => "init";

@Riverpod(dependencies: [initData])
class DataCombo extends _$DataCombo {
  @override
  String build() => "${ref.watch(initDataProvider)} combo";

  void update() {
    state = "$state update";
  }
}

@Riverpod(dependencies: [DataCombo])
String dataComboFilter(DataComboFilterRef ref, {required String filter}) =>
    ref.watch(dataComboProvider.select((value) => "$value $filter"));

class ShowDataWidget extends StatelessWidget {
  const ShowDataWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return ProviderScope(
        overrides: [initDataProvider],
        child: Consumer(
          builder: (context, ref, child) {
            return Row(children: [
              Text(ref.watch(dataComboFilterProvider(filter: "filter"))),
              IconButton(
                  onPressed: () {
                    ref.read(dataComboProvider.notifier).update();
                  },
                  icon: const Icon(Icons.update))
            ]);
          },
        ));
  }
}

Expected behavior

I ran into this error and it was related to the way I was using it, and there was an explicit warning. But I don't have a good way to deal with it.

image

I have a standalone library that uses riverpod, which provides a widget to the outside world. But projects using this library don't want to depend on riverpod.

Just like in the example above, my library exposes ShowDataWidget and uses some state. I can only add ProviderScope on ShowDataWidget. How can I avoid passing riverpod dependency to the consumer.

In addition, is this problem normal? My understanding is that each ShowDataWidget has its own independent ProviderScope and does not need to share data with other brothers.

@hcanyz hcanyz added bug Something isn't working needs triage labels Nov 15, 2023
@rrousselGit
Copy link
Owner

I have a standalone library that uses riverpod, which provides a widget to the outside world. But projects using this library don't want to depend on riverpod.

Feel free to disable the lint if it doesn't apply to you.

@rrousselGit rrousselGit added this to the Riverpod 3.0 milestone Nov 15, 2023
@hcanyz
Copy link
Author

hcanyz commented Nov 16, 2023

Now I can only rely on riverpod in projects that use this library. Is there any temporary solution to solve this crash?

@rrousselGit
Copy link
Owner

I do not know what is causing this yet. I have yet to investigate the issue. We'll see

rrousselGit added a commit to josh-burton/riverpod that referenced this issue Nov 20, 2023
rrousselGit pushed a commit that referenced this issue Nov 20, 2023
rrousselGit added a commit that referenced this issue Nov 20, 2023
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
2 participants