导航到不同的路线后,Flutter 找不到正确的 Provider<Bloc>
Flutter could not find the correct Provider<Bloc> after navigating to different route
我正在使用 bloc 来处理注册表单的状态。但我得到错误:
Error: Could not find the correct Provider<CreateDidBloc> above this BlocBuilder<CreateDidBloc, CreateDidState> Widget
.
正如您在错误中看到的那样,我确实使用了 bloc CreateDidBloc
和状态 CreateDidState
并通过 BlocBuilder 获取它们。
BlocBuilder 位于我的“注册”页面中,在我的示例中称为 Creation
。当我从我的介绍页面导航到创建页面时出现错误。
下面是我的 MaterialApp
的摘录,其中我用 RepositoryProvider
和 BlocProvider
包装创建页面,以便创建页面可以访问 Bloc 和存储库。但是由于某种原因,creation
页面在导航到创建页面后找不到 CreateDidBloc
的 BlocProvider。
initialRoute: "/introduction",
routes: {
"/introduction": (context) => Introduction(),
"/create": (context) => RepositoryProvider(
create: (context) => CreateDidRepository(),
child: BlocProvider(
create: (BuildContext context) => CreateDidBloc(
repo: context.read<CreateDidRepository>(),
),
child: Creation(),
),
),
},
这是我导航到 Creation
屏幕的方式:
Navigator.push(context,
PageTransition(type: PageTransitionType.fade, child: Creation()));
创建(注册)页面:
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Column(
children: [
Expanded(
child: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: _pageController,
onPageChanged: (index) {
setState(() => currentStep = index);
},
children: [
Step1(),
Step2(),
Step3(),
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
BlocBuilder<CreateDidBloc, CreateDidState>(
builder: (context, state) {
return ElevatedButton(
onPressed: () {
next();
},
child: Text(L.of(context).next));
},
),
BlocBuilder<CreateDidBloc, CreateDidState>(
builder: (context, state) {
return OutlinedButton(
onPressed:
state.formStatus is FormSubmitting ? null : cancel,
child: Text(L.of(context).back));
},
)
],
),
const SizedBox(
height: 16,
)
],
)));
}
这是堆栈跟踪:
When the exception was thrown, this was the stack
#0 Provider._inheritedElementOf
#1 Provider.of
#2 ReadContext.read
#3 _BlocBuilderBaseState.initState
#4 StatefulElement._firstBuild
我找到了我的 BlocBuilder 导航后找不到 CreateDidBloc
的原因。发生该错误是因为在 Flutter 中导航会将您的页面推送到小部件树中 MaterialApp 的正下方。这意味着我新导航的页面位于 BlocProvider 之上,它在 MaterialApp 下方的小部件树中指定。
为了解决这个问题,我只是用 MultiBlocProvider 和 RepositoryProvider 包装了我的 MaterialApp,这样无论我在什么路线,Bloc 都是全局提供的。
这是我可以在其中全局定义 blocs 的重要摘录:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RepositoryProvider(
create: (context) => CreateDidRepository(),
child: MultiBlocProvider(
providers: [
BlocProvider<LanguageBloc>(
create: (context) =>
LanguageBloc(LanguagePreference.getLanguage())),
BlocProvider<CreateDidBloc>(
create: (context) =>
CreateDidBloc(repo: context.read<CreateDidRepository>()))
],
child: BlocBuilder<LanguageBloc, LanguageState>(
builder: (context, state) {
return MaterialApp(...)
我正在使用 bloc 来处理注册表单的状态。但我得到错误:
Error: Could not find the correct Provider<CreateDidBloc> above this BlocBuilder<CreateDidBloc, CreateDidState> Widget
.
正如您在错误中看到的那样,我确实使用了 bloc CreateDidBloc
和状态 CreateDidState
并通过 BlocBuilder 获取它们。
BlocBuilder 位于我的“注册”页面中,在我的示例中称为 Creation
。当我从我的介绍页面导航到创建页面时出现错误。
下面是我的 MaterialApp
的摘录,其中我用 RepositoryProvider
和 BlocProvider
包装创建页面,以便创建页面可以访问 Bloc 和存储库。但是由于某种原因,creation
页面在导航到创建页面后找不到 CreateDidBloc
的 BlocProvider。
initialRoute: "/introduction",
routes: {
"/introduction": (context) => Introduction(),
"/create": (context) => RepositoryProvider(
create: (context) => CreateDidRepository(),
child: BlocProvider(
create: (BuildContext context) => CreateDidBloc(
repo: context.read<CreateDidRepository>(),
),
child: Creation(),
),
),
},
这是我导航到 Creation
屏幕的方式:
Navigator.push(context,
PageTransition(type: PageTransitionType.fade, child: Creation()));
创建(注册)页面:
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Column(
children: [
Expanded(
child: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: _pageController,
onPageChanged: (index) {
setState(() => currentStep = index);
},
children: [
Step1(),
Step2(),
Step3(),
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
BlocBuilder<CreateDidBloc, CreateDidState>(
builder: (context, state) {
return ElevatedButton(
onPressed: () {
next();
},
child: Text(L.of(context).next));
},
),
BlocBuilder<CreateDidBloc, CreateDidState>(
builder: (context, state) {
return OutlinedButton(
onPressed:
state.formStatus is FormSubmitting ? null : cancel,
child: Text(L.of(context).back));
},
)
],
),
const SizedBox(
height: 16,
)
],
)));
}
这是堆栈跟踪:
When the exception was thrown, this was the stack
#0 Provider._inheritedElementOf
#1 Provider.of
#2 ReadContext.read
#3 _BlocBuilderBaseState.initState
#4 StatefulElement._firstBuild
我找到了我的 BlocBuilder 导航后找不到 CreateDidBloc
的原因。发生该错误是因为在 Flutter 中导航会将您的页面推送到小部件树中 MaterialApp 的正下方。这意味着我新导航的页面位于 BlocProvider 之上,它在 MaterialApp 下方的小部件树中指定。
为了解决这个问题,我只是用 MultiBlocProvider 和 RepositoryProvider 包装了我的 MaterialApp,这样无论我在什么路线,Bloc 都是全局提供的。
这是我可以在其中全局定义 blocs 的重要摘录:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RepositoryProvider(
create: (context) => CreateDidRepository(),
child: MultiBlocProvider(
providers: [
BlocProvider<LanguageBloc>(
create: (context) =>
LanguageBloc(LanguagePreference.getLanguage())),
BlocProvider<CreateDidBloc>(
create: (context) =>
CreateDidBloc(repo: context.read<CreateDidRepository>()))
],
child: BlocBuilder<LanguageBloc, LanguageState>(
builder: (context, state) {
return MaterialApp(...)