在小部件树中找不到 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: ...,
);
因为代码太大我会尝试用文字总结一下。
这是最新的异常:
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: ...,
);