在小部件树中找不到 Bloc

Bloc isn't found in the widget tree

因为代码太大我会尝试用文字总结一下。

这是最新的异常:

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.

在屏幕 1 中,我有以下构建方法:

    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());
      },
    );
  }

我在 AdminProdEntryScreen 中再次执行:

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

在 EntryProdSearchScreen 中,我从上面得到错误。

为什么在小部件树中找不到 BloC/Cubit?

我什至使用了多个 Builder 小部件,但我总是遇到这个异常。

当您提供 BLoC 时,它可以访问当前的小部件树,当您导航到另一个屏幕时,它将无法访问该 BLoC。 您可以通过以下两种方式之一解决此问题。

1
你用一个 bloc (Multi) 提供程序包装你的整个应用程序,无论导航如何,你都可以访问该 bloc。
之所以可行,是因为您将导航包装在 MaterialApp 和 bloc 提供程序中。

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

2
您可以通过导航路线传递 bloc 的实例,并使用 BlocProvider.value 提供 same 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: ...,
);