You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter用Cubit/Bloc实现登录时加载卡顿及数据传递问题解决

问题解决:登录Cubit卡顿+错误信息传递实现

一、核心问题分析

  1. 卡顿原因:错误状态类名拼写错误(Widget中写的ErrorAuthentification与实际状态类ErrorSignInAuth不符),导致错误状态无法被捕获,等待弹窗一直叠加显示;同时状态切换时未关闭之前的等待弹窗,引发路由栈混乱。
  2. 错误信息传递缺失:ErrorSignInAuth状态未携带错误码和消息字段,无法将API响应信息传递到UI层。

二、分步解决方案

1. 改造错误状态类,支持传递错误信息

修改AuthState文件中的ErrorSignInAuth类,新增错误码和消息字段:

class ErrorSignInAuth extends AuthState {
  final int statusCode;
  final String message;

  const ErrorSignInAuth({
    required super.email,
    required super.password,
    required this.statusCode,
    required this.message,
  });

  @override
  List<Object?> get props => [email, password, statusCode, message];
}

2. 在Cubit中捕获并传递API错误信息

更新AuthCubit的signIn方法,提取Dio错误的状态码和消息,emit到错误状态:

Future signIn() async {
  emit(WaitingSignInAuth(state.email, state.password));
  try {
    final data = await _apiService.signIn(
      email: state.email ?? "",
      password: state.password ?? ""
    );
    if (data['success']) {
      print(data);
      emit(const SuccessAutentification());
    }
  } on DioError catch (ex) {
    print(ex.toString());
    // 提取API返回的错误信息,兜底默认值
    final statusCode = ex.response?.statusCode ?? 500;
    final errorMessage = ex.response?.data['message'] ?? '登录失败,请稍后重试';
    
    emit(ErrorSignInAuth(
      email: state.email,
      password: state.password,
      statusCode: statusCode,
      message: errorMessage,
    ));
  } catch (e) {
    print(e);
    // 处理非Dio异常
    emit(ErrorSignInAuth(
      email: state.email,
      password: state.password,
      statusCode: 500,
      message: '未知错误,请稍后重试',
    ));
  }
}

3. 修复Widget中的状态判断与弹窗逻辑

修正类名拼写错误,同时确保状态切换时关闭等待弹窗,避免叠加:

@override
Widget build(BuildContext context) {
  return BlocConsumer<AuthCubit, AuthState>(
    listener: (context, state) {
      if (state is WaitingSignInAuth) {
        showDialog(
          context: context,
          barrierDismissible: false, // 禁止外部点击关闭等待弹窗
          builder: (context) => Container(
            width: MediaQuery.of(context).size.width,
            height: MediaQuery.of(context).size.height,
            color: Colors.black.withOpacity(0.6),
            child: const Center(
              child: CircularProgressIndicator(
                strokeWidth: 1,
                color: Colors.black,
                backgroundColor: Colors.white,
              ),
            ),
          ),
        );
      }
      if (state is SuccessAutentification) {
        // 先关闭等待弹窗,再跳转页面
        Navigator.of(context).pop();
        Navigator.of(context).pushReplacement(
          MaterialPageRoute(builder: (_) => const MainWidget()),
        );
      }
      if (state is ErrorSignInAuth) {
        // 先关闭等待弹窗,再弹出错误提示
        Navigator.of(context).pop();
        showDialog(
          context: context,
          builder: (context) => AlertDialog(
            title: Text("错误 ${state.statusCode}"),
            content: SingleChildScrollView(
              child: ListBody(children: [Text(state.message)]),
            ),
            actions: [
              TextButton(
                child: const Text("关闭"),
                onPressed: () => Navigator.of(context).pop(),
              )
            ],
          ),
        );
      }
    },
    builder: (context, state) {
      return Scaffold(
        body: LoginButton(
          color: _isValid ? AppColors.white : AppColors.whiteA3A3A3,
          text: "Login in",
          textColor: Colors.black,
          isButtonDisabled: !_isValid,
          onPressed: () {
            if (_key.currentState!.validate()) {
              // 使用context.read替代BlocProvider.of,更简洁
              context.read<AuthCubit>().setEmail(_email.text.trim());
              context.read<AuthCubit>().setPassword(_password.text.trim());
              context.read<AuthCubit>().signIn();
              _key.currentState!.save();
            }
          },
        ),
      );
    },
  );
}

内容的提问来源于stack exchange,提问作者newbiras

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 00:45:43