BlocProvider.of() 被调用时,使用了不包含 HomeBloc 的上下文。

huangapple go评论69阅读模式
英文:

BlocProvider.of() called with a context that does not contain a HomeBloc

问题

Sure, here is the translated content without the code parts:

  1. I first defined a class that can record Bloc and GoRouterWidgetBuilder, collectively referred to as RouterWidgetBuilder.

  2. I initialized a map in the following format:

    • For the route "/":

      • It uses a RouterWidgetBuilder with HomeBloc and the MyHomeScreen as the builder.
    • For the route "/details":

      • It uses a RouterWidgetBuilder with DetailBloc and the DetailsScreen as the builder.

I printed it through the logger and found that homeBuilder!.create is HomeBloc. However, in HomeScreen, when using BlocProvider.of<HomeBloc>(context), an error is reported: "BlocProvider.of() called with a context that does not contain a HomeBloc."

May I ask how to solve this problem: "BlocProvider.of() called with a context that does not contain a HomeBloc."

英文:

**1、**I first defined a class that can record Bloc and GoRouterWidgetBuilder,The following collectively refer to it as: RouterWidgetBuilder

**2、**I initialized a map in the following format:

  static final GoRouter routers = RouterX.generateRoutes(
    routeMaps: {
      &quot;/&quot; :  RouterWidgetBuilder(
        create: HomeBloc(),
        builder: (context, params) =&gt; const MyHomeScreen(),
      ),

      &quot;/details&quot; :  RouterWidgetBuilder(
        create: DetailBloc(),
        builder: (context, params) =&gt; const DetailsScreen(),
      ),

    }
  );
GoRouter(
      errorBuilder: (context, state) {
        logger.e(state.error);
        return PageNotFound();
      },
      routes: &lt;RouteBase&gt;[
        GoRoute(
          path: &quot;/&quot;,
          builder: (BuildContext context, GoRouterState state) {
            return BlocProvider(
              create: (context) =&gt;  homeBuilder!.create,
              child: homeBuilder!.builder(context, state),
            );
          },
          routes: otherPageRouters,
        ),
      ],
    )

I printed it through the logger and found that homeBuilder!.create is HomeBloc

But in HomeScreen, through BlocProvider.of<HomeBloc>(context), an error is reported:

BlocProvider.of() called with a context that does not contain a HomeBloc.

May I ask how to solve this problem: BlocProvider.of() called with a context that does not contain a HomeBloc.

答案1

得分: 1

This is a standard mistake. Your RouterWidgetBuilder is a class without generics and thus the type of RouterWidgetBuilder.create is Bloc and not HomeBloc, which makes the Provider also provide the implicit type Bloc. If you want to continue using your RouterWidgetBuilder, you should add a generic:

class RouterWidgetBuilder<B extends Bloc>{
   final B create;
   ...
}

Also, your create should be a function, since the Bloc is initialized before there is even a Provider to dispose it. Because of this you can not use your RouterWidgetBuilder more than once. Currently your create object is disposed as soon as a the first Provider is disposed and cannot be created again, since you don't use a function for create.

EDIT:
If you absolutely want to keep your structure, you can move the builder from your widget to the RouterWidgetBuilder class, which will allow you to use the appropriate generics of the right type here:

GoRoute(
     path: "/",
     builder: (BuildContext context, GoRouterState state) {
       return homeBuilder!.completeBuilder(context, state);
    },
    routes: otherPageRouters,
)

class RouterWidgetBuilder<B extends StateStreamableSource>{
   final B Function(BuildContext context) create;
   ...
   Widget completeBuilder(BuildContext context, GoRouterState state){
     return BlocProvider<B>(
        create: create,
        child: builder(context, state),
     );
   }
}
英文:

This is a standard mistake. Your RouterWidgetBuilder is a class without generics and thus the type of RouterWidgetBuilder.create is Bloc and not HomeBloc, which makes the Provider also provide the implicit type Bloc. If you want to continue using your RouterWidgetBuilder, you should add a generic:

class RouterWidgetBuilder&lt;B extends Bloc&gt;{
   final B create;
   ...
}

Also, your create should be a function, since the Bloc is initialized before there is even a Provider to dispose it. Because of this you can not use your RouterWidgetBuilder more than once. Currently your create object is disposed as soon as a the first Provider is disposed and cannot be created again, since you don't use a function for create.

EDIT:
If you absolutely want to keep your structure, you can move the builder from your widget to the RouterWidgetBuilder class, which will allow you to use the appropriate generics of the right type here:

GoRoute(
     path: &quot;/&quot;,
     builder: (BuildContext context, GoRouterState state) {
       return homeBuilder!.completeBuilder(context, state);
    },
    routes: otherPageRouters,
)

class RouterWidgetBuilder&lt;B extends StateStreamableSource&gt;{
   final B Function(BuildContext context) create;
   ...
   Widget completeBuilder(BuildContext context, GoRouterState state){
     return BlocProvider&lt;B&gt;(
        create: create,
        child: builder(context, state),
     );
   }
}

huangapple
  • 本文由 发表于 2023年6月8日 17:07:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76430272.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定