Flutter Cubit 状态发射两次

问题描述 投票:0回答:1

在 Flutter 中,当我调用下面的 cubit 方法时,状态被发射两次。

有人可以帮我找出我的代码有什么问题吗?

肘级:

class AlertCubit extends Cubit<AlertState> {
  AlertCubit() : super(AlertInitial());

  void alert(InfoAlertData alertInfo) {
    emit(AlertInitial());
    **emit(NewAlert(alertInfo));**
  }
}

我从另一肘调用这个函数的地方:

class CustomersCubit extends Cubit<CustomersState> {
  CustomersCubit(
      {required this.alertCubit,
    })
      : super(CustomersInitial());

  final AlertCubit alertCubit;

///removed irrelevant code

void markMissing(int loanId) async {
    if (collectionCubit.active) {
    } else {
      **alertCubit.alert(InfoAlerts.startCollect);**
    }
  }

///removed irrelevant code
}

我在 main 中传递了 cubit 作为参数:

///removed irrelevant code

return MultiBlocProvider(
      providers: [
        BlocProvider(
          create: (_) => AlertCubit(),
        ),
        BlocProvider(
          create: (BuildContext cusContext) => CustomersCubit(
            **alertCubit: BlocProvider.of<AlertCubit>(cusContext),**
          ),
        ),
///removed irrelevant code

我是 flutter 和 bloc 的新手;感谢任何帮助

flutter state cubit
1个回答
0
投票

您遇到的问题是由于在 AlertCubit 中快速连续发出多个状态,这会导致任何侦听器做出两次反应。在您的警报方法中,您在 NewAlert(alertInfo) 之前立即发出 AlertInitial():

void alert(InfoAlertData alertInfo) {
   emit(AlertInitial());
   emit(NewAlert(alertInfo));
}

这会导致每次调用alert() 时都会发生两次状态更改。如果您的 UI 或任何侦听器设置为响应状态更改,它们将对两种发射做出反应,这可能不是所需的行为。

解决方案 要解决此问题,您应该在触发新警报时仅发出 NewAlert 状态。 AlertInitial 状态通常在首次初始化肘节时使用,除非您重置状态,否则不需要再次发出。 以下是修改 AlertCubit 的方法:

class AlertCubit extends Cubit<AlertState> {
AlertCubit() : super(AlertInitial());

void alert(InfoAlertData alertInfo) {
emit(NewAlert(alertInfo));
  }
}

通过删除 emmit(AlertInitial());,您可以确保在调用alert() 时仅发生一次状态更改,从而防止 UI 中发生重复反应。

其他注意事项

  1. 重置状态:如果您需要在处理 NewAlert 后将状态重置回 AlertInitial,请考虑在显示或处理警报之后执行此操作,而不是在发出 NewAlert 之前立即执行此操作。这可以在监听 AlertCubit 的 UI 组件中完成

  2. UI 侦听器设置:确保您的 UI 已正确设置为侦听状态更改,而不会导致多次重建或反应。这是使用 BlocListener 的示例:

    BlocListener<AlertCubit, AlertState>(
      listener: (context, state) {
       if (state is NewAlert) {
        // Display the alert (e.g., show a dialog or snackbar)
        showDialog(
         context: context,
         builder: (_) => AlertDialog(
          title: Text('Alert'),
          content: Text(state.alertInfo.message),
          actions: [
           TextButton(
           onPressed: () {
             Navigator.of(context).pop();
           },
           child: Text('OK'),
          ),
         ],
        ),
       );
      }
     },
     child: YourWidget(),
    );
    

在此示例中:

  1. 监听器仅在状态为 NewAlert 时做出反应。
  2. 处理警报后(例如,用户关闭对话框),如有必要,您可以将状态重置回 AlertInitial。

总结

  1. 删除冗余状态发射:消除emit(AlertInitial());从您的alert()方法中防止不必要地发出多个状态。
  2. 管理 UI 中的状态:如果需要重置状态,请考虑在 UI 中处理警报后执行此操作,而不是在发出新警报之前立即执行此操作。
  3. 检查多个侦听器:确保您的 UI 没有可能导致重复反应的多个侦听器。

通过进行这些更改,您的 AlertCubit 应仅在每个警报中发出一次状态,并且您的 UI 应适当响应,而不会出现重复的警报。

© www.soinside.com 2019 - 2024. All rights reserved.