Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
5.6k views
in Technique[技术] by (71.8m points)

flutter provider - Bloc isn't found in the widget tree

Because the code is to big I will try and sum it up in words.

This is the latest exception:

Error: Could not find the correct Provider<ProdEntriesSearchCubit> above this BlocListener<ProdEntriesSearchCubit, ProdEntriesSearchState> Widget

This likely happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:

- The provider you are trying to read is in a different route.

  Providers are "scoped". So if you insert of provider inside a route, then
  other routes will not be able to access that provider.

- You used a `BuildContext` that is an ancestor of the provider you are trying to read.

  Make sure that BlocListener<ProdEntriesSearchCubit, ProdEntriesSearchState> is under your MultiProvider/Provider<ProdEntriesSearchCubit>.
  This usually happens when you are creating a provider and trying to read it immediately.

In screen 1 I have the following build method:

    Widget build(BuildContext context) {
        final entriesState = context.watch<ProdEntriesCubit>().state;
        return BlocProvider(
          create: (context) => ProdEntriesSearchCubit(
            productsRepository: context.watch<ProductsRepository>(),
          ),
          child: Builder(
            builder: (context) => SafeScreen(
              child: Scaffold(
                body: _buildBody(context, entriesState: entriesState),
                floatingActionButton: _buildFab(context),
              ),
            ),
          ),
        );
      }

_buildFab(BuildContext context) {
    return FloatingActionButton(
      child: Icon(
        Icons.add,
        color: Colors.white,
      ),
      onPressed: () async {
        await navigatorPush(context, screen: AdminProdEntryScreen());
      },
    );
  }

In AdminProdEntryScreen I do again:

navigatorPush(
          context,
          screen: EntryProdSearchScreen(),
        );

In EntryProdSearchScreen I get the error from above.

Why is the BloC/Cubit not found in the widget tree?

I even used multiple Builder widgets but I am always hit by this exception.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When you provide your BLoC, it has access to the current widget tree, when you navigate to another screen it won't have access to that BLoC. You can solve this in one of two ways.

1
You wrap your whole app with a bloc (Multi) provider that you can access the bloc no matter the navigation.
The reason that this works is because you are wrapping your navigation within MaterialApp with the bloc provider.

  runApp(
    MultiBlocProvider(
      providers: [
        BlocProvider<ProdEntriesSearchCubit>(
          create: (context) => ProdEntriesSearchCubit(),
        ),
      ],
      child: MyApp(),
    ),
  );

2
You can pass an instance of the bloc through the nav route and use BlocProvider.value to provide the same instance of the bloc.


//nav method
Navigator.of(context).pushNamed(
  '/entry_prod_search_screen',
  arguments: context.read< ProdEntriesSearchCubit >(),
);

//in the navigated route screen
final bloc = ModalRoute.of(context).settings.arguments;

return MultiBlocProvider(
  providers: [
    BlocProvider.value(
      value: bloc,
    ),
  ],
  child: ...,
);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...