Flutter 在 BlocConsumer Widget 上面找不到正确的 Provider
Flutter could not find the correct Provider above BlocConsumer Widget
我正在为一个项目使用 Flutter Bloc
。
这是结构:
MultiBlocProvider(
providers: [
BlocProvider<BlocA>(
create: (context) {
return BlocA()
..add(FetchEvent());
},
),
BlocProvider<BlocC>(
create: (context) {
return BlocC()..add(FetchEvent());
},
),
],
child: IndexedStack(
index: _pageNum,
children: [
ChildA(),
ChildB(),
],
),
)
内部 ChildB
我有一个 Navigator.push()
到一个 ChildC
,其中使用了 BlocC
(BlocConsumer
),但我得到了一个错误,
Flutter could not find the correct Provider above BlocConsumer<BlocC> Widget
编辑
ChildB
中有一个按钮,按下后会导航到 ChildC
。
喜欢,
TextButton( // this code exists inside a scaffold widget
child: Text("Page C"),
onPressed: () {
Navigator.push(context, CupertinoPageRoute(builder: (context) => ChildC()));
}
),
这是 ChildC
的集团消费者
// Child C
Scaffold(
body: BlocConsumer<BlocC, CState>(
builder: (context, state) {
if(state is CSuccessState) {
return _body();
} else if (state is CLoadingState || state is CInitState) {
return Center(child: CircularProgressIndicator());
} else return Center(child: Text("Something went wrong"));
},
listener: (context, state) {},
),
);
编辑 2
我找到了 答案,显然,这是使用 Navigator.push
时的问题。不过,如果有人知道如何解决我的问题,请告诉我
导航器的行为是预期的。
你应该更换
Navigator.push(context, CupertinoPageRoute(builder: (context) => ChildC()));
与
Navigator.push(context, CupertinoPageRoute(builder: (ctx) => BlocProvider.value(value: context.read<BlocC>()), child: ChildC());
这会起作用。
提供程序是有范围的。
这意味着只有您的提供者的子树(您的子小部件)可以访问它。
当你推送一个新页面时,它会将它推送到 MaterialApp
路由器(你的应用程序的默认根路由器),你的小部件树看起来像:
MaterialApp
|- Provider
| |- TextButton (with onPressed: () => Navigator.push())
|- ChildC
如您所见,您的 ChildC
不低于 Provider
(s)。
1。将您的供应商移到 material 应用
之上
解决它的一种方法是将您的提供商移至 MaterialApp
:
Provider
|- MaterialApp
| |- TextButton (with onPressed: () => Navigator.push())
| |- ChildC
2。使用嵌套路由器
您可以将页面推送到 Provider
下方的嵌套路由器:
MaterialApp
|- Provider
| |- Router
| | |- TextButton (with onPressed: () => Navigator.push())
| | |- ChildC
3。再次提供您的 BlockC
以上 ChildC
:
TextButton( // this code exists inside a scaffold widget
child: Text("Page C"),
onPressed: () {
final blockCValue = context.read<BlockC>();
Navigator.push(
context,
CupertinoPageRoute(builder: (context) => Provider<BlockC>.value(
value: blockCValue,
child: ChildC(),
),
);
},
),
我正在为一个项目使用 Flutter Bloc
。
这是结构:
MultiBlocProvider(
providers: [
BlocProvider<BlocA>(
create: (context) {
return BlocA()
..add(FetchEvent());
},
),
BlocProvider<BlocC>(
create: (context) {
return BlocC()..add(FetchEvent());
},
),
],
child: IndexedStack(
index: _pageNum,
children: [
ChildA(),
ChildB(),
],
),
)
内部 ChildB
我有一个 Navigator.push()
到一个 ChildC
,其中使用了 BlocC
(BlocConsumer
),但我得到了一个错误,
Flutter could not find the correct Provider above BlocConsumer<BlocC> Widget
编辑
ChildB
中有一个按钮,按下后会导航到 ChildC
。
喜欢,
TextButton( // this code exists inside a scaffold widget
child: Text("Page C"),
onPressed: () {
Navigator.push(context, CupertinoPageRoute(builder: (context) => ChildC()));
}
),
这是 ChildC
// Child C
Scaffold(
body: BlocConsumer<BlocC, CState>(
builder: (context, state) {
if(state is CSuccessState) {
return _body();
} else if (state is CLoadingState || state is CInitState) {
return Center(child: CircularProgressIndicator());
} else return Center(child: Text("Something went wrong"));
},
listener: (context, state) {},
),
);
编辑 2
我找到了 Navigator.push
时的问题。不过,如果有人知道如何解决我的问题,请告诉我
导航器的行为是预期的。
你应该更换
Navigator.push(context, CupertinoPageRoute(builder: (context) => ChildC()));
与
Navigator.push(context, CupertinoPageRoute(builder: (ctx) => BlocProvider.value(value: context.read<BlocC>()), child: ChildC());
这会起作用。
提供程序是有范围的。
这意味着只有您的提供者的子树(您的子小部件)可以访问它。
当你推送一个新页面时,它会将它推送到 MaterialApp
路由器(你的应用程序的默认根路由器),你的小部件树看起来像:
MaterialApp
|- Provider
| |- TextButton (with onPressed: () => Navigator.push())
|- ChildC
如您所见,您的 ChildC
不低于 Provider
(s)。
1。将您的供应商移到 material 应用
之上解决它的一种方法是将您的提供商移至 MaterialApp
:
Provider
|- MaterialApp
| |- TextButton (with onPressed: () => Navigator.push())
| |- ChildC
2。使用嵌套路由器
您可以将页面推送到 Provider
下方的嵌套路由器:
MaterialApp
|- Provider
| |- Router
| | |- TextButton (with onPressed: () => Navigator.push())
| | |- ChildC
3。再次提供您的 BlockC
以上 ChildC
:
TextButton( // this code exists inside a scaffold widget
child: Text("Page C"),
onPressed: () {
final blockCValue = context.read<BlockC>();
Navigator.push(
context,
CupertinoPageRoute(builder: (context) => Provider<BlockC>.value(
value: blockCValue,
child: ChildC(),
),
);
},
),