在 Flutter 中使用 Bloc/Cubit 时绕过 CONTEXT

Posted

技术标签:

【中文标题】在 Flutter 中使用 Bloc/Cubit 时绕过 CONTEXT【英文标题】:Get around of CONTEXT while using Bloc/Cubit in Flutter 【发布时间】:2021-01-06 02:58:27 【问题描述】:

我做了一段时间的flutter,一直在使用setState()。最近决定学习BLoC。现在在 v6 中,Bloc 带有 Cubit,因此开始跟进 BLoC-Cubit 的教程,了解它们如何工作以及如何实现。到目前为止,无论我学到什么,我都在一个演示项目中实现了。

我遇到了这个错误:

使用不包含 Cubit 类型的 Cubit 的上下文调用 BlocProvider.of()。

从传递给 BlocProvider.of() 的上下文开始找不到祖先。

如果您使用的上下文来自 BlocProvider 上方的小部件,则会发生这种情况。

使用的上下文是:BlocConsumer(dirty)

The relevant error-causing widget was BlocConsumer<Cubit<dynamic>, dynamic> 这会将我重定向到 CreateProfile.dart 行号。 3、查看下方。

我猜这个错误与我没有将正确的上下文传递给 CreateProfile 的 BlocConsumer 的上下文有关。但是,登录和 Otp 页面中的 Bloc 工作正常。

小部件树去:Main->Splash->Login->Otp->CreateProfile.

如果我的不正确,请帮我解决这个问题,并提出正确的 bloc 实施做法。

main.dart

class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      debugShowCheckedModeBanner: false,
        home: Splash(),
        routes: 
          Splash.id : (context) => Splash(),
        ,
    );
   

飞溅飞镖

FlatButton(
  onTap: ()
    Navigator.push(context, MaterialPageRoute(builder: (context) => BlocProvider(
      create: (context) => LoginCubit(),
      child: Login(),)));
    ,
  child: Text('Get Started', style: kText18SemiBold.copyWith(color: Colors.white)),
),

登录.dart

return Scaffold(
    backgroundColor: kBackgroundColor,
    body: BlocConsumer<LoginCubit, LoginState>(
      listener: (context, state) 
        if(state is LoginApiSuccess)
          Navigator.push(context, MaterialPageRoute(builder: (context) => BlocProvider(
            create: (context) => OtpCubit(),
            child: Otp(),
          )));
        
      ,
      builder: (context, state) 
        return Stack(
          // Contains Login UI 
        )
      
    )
);

Otp.dart

return Scaffold(
    backgroundColor: kBackgroundColor,
    body: BlocConsumer<OtpCubit, OtpState>(
      listener: (context, state) 
        if(state is OtpApiSuccess)
          Navigator.push(context, MaterialPageRoute(builder: (context) => BlocProvider(
            create: (context) => CreateprofileCubit(),
            child: CreateProfile(),
          )));
        
      ,
      builder: (context, state) 
        return Stack(
          // Contains OTP UI 
        )
      
    )
);

CreateProfile.dart

return Scaffold(
    backgroundColor: kBackgroundColor,
    body: BlocConsumer<CreateprofileCubit, CreateprofileState>( // Error redirects here
      listener: (context, state) 
        if(state is ProfileCreated)
          Navigator.push(context, MaterialPageRoute(builder: (context) => AddProfileImages(),));
        
      ,
      builder: (context, state) 
        return Stack(
          // Contains CreateProfile UI 
        )
      
    )
);

【问题讨论】:

【参考方案1】:

BlocProvider 是一个泛型类,你需要为它提供一个类型。尝试替换:

BlocProvider(
   create: (context) => OtpCubit(),
   child: Otp(),
)

与:

BlocProvider<OtpCubit>(
   create: (context) => OtpCubit(),
   child: Otp(),
)

同样的事情适用于您使用的所有其他 BlocProviders。

【讨论】:

谢谢你这工作,但为什么它没有导致登录或 otp 错误?

以上是关于在 Flutter 中使用 Bloc/Cubit 时绕过 CONTEXT的主要内容,如果未能解决你的问题,请参考以下文章

Flutter BLoC 库:将 TextEditingController 对象保存在哪里:在 State、BLoC / Cubit 类中还是在小部件中?

Flutter BLoC/Cubit STATE 类最佳实践

具有多个firebase请求的flutter bloc cubit最佳实践

我应该先启动 Cubit,然后再将代码重构为 Bloc 吗?

使用相同 Bloc/Cubit 的多个 BlocBuilder,每个 BlocBuilder 用于不同的事件

当网络连接恢复时,使用 Bloc /Cubit 颤振不会发生自动刷新?