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