Bloc入门之Bloc详解

背景

之前一起学习了 Cubit ,现在进一步学习 Bloc

区别

首先应该了解一下 CubitBloc 各自的优势,以便按需使用

在这里插入图片描述

在这里插入图片描述
从上面两图可以看出,在使用cubit时,UI通过function通知cubit进行数据处理和state更新,而使用bloc时,则是通过event来通知bloc进行数据处理和state更新。

  1. Cubit 的优势:

简单

创建一个 Cubit 时,只需要定义状态以及我们想要公开的改变状态的函数
创建一个 Bloc 时,必须定义状态、事件和 EventHandler

  1. Bloc 的优势

可溯源

可以查看什么事件引发了状态改变。

能够控制和转换事件的传入流

像下面的样子,就很轻松实现防抖的效果:

EventTransformer<T> debounce<T>(Duration duration) {
  return (events, mapper) => events.debounceTime(duration).flatMap(mapper);
}

CounterBloc() : super(0) {
  on<Increment>(
    (event, emit) => emit(state + 1),
    transformer: debounce(const Duration(milliseconds: 300)),
  );
}

上手

  1. 创建一个Bloc
abstract class CounterEvent {}
// 定义事件
class CounterIncrementPressed extends CounterEvent {}

class CounterBloc extends Bloc<CounterEvent, int> {
  CounterBloc() : super(0){// 可以指定初始状态,此处0
	on<CounterIncrementPressed>((event, emit) { //EventHandler 事件处理函数
      // 可以通过 state getter 方法访问 bloc 的当前状态和通过 emit(state + 1) 改变状态.
      emit(state + 1);
    });
    // 可以重写onchange 来观察状态的改变
    @override
  	void onChange(Change<int> change) {
      super.onChange(change);
      print(change);
      //输出Change { currentState: 0, nextState: 1 }
  	}
	//通过重写onTransition 我们还可以观察到时什么事件出发了本次状态改变
    @override
    void onTransition(Transition<CounterEvent, int> transition) {
      super.onTransition(transition);
      print(transition);
      // 输出Transition { currentState: 0, event: Instance of 'CounterIncrementPressed', nextState: 1 }
    }
    @override // bloc独有的,可以观察事件
    void onEvent(CounterEvent event) {
      super.onEvent(event);
      print(event);
    }
  }
}

这里有两点需要注意:

Bloc 不可以直接发出状态,所有状态都应该是通过EventHandler函数发出的。

Bloc 和 Cubits 都会忽略重复的状态,也就是说如果currentState与nextState一致,则本次状态变化会被忽略。

除了在Bloc类里面重写方法来观察状态,也可以和之前一样也可以通过将观察部分单独写在BlocObserver类中:
触发时,先触发Bloc本地的方法,然后再触发BlocObserver的全局方法。

class SimpleBlocObserver extends BlocObserver {
  @override
  void onChange(BlocBase bloc, Change change) {
    super.onChange(bloc, change);
    print('${bloc.runtimeType} $change');
  }

  @override
  void onTransition(Bloc bloc, Transition transition) {
    super.onTransition(bloc, transition);
    print('${bloc.runtimeType} $transition');
  }

  @override
  void onError(BlocBase bloc, Object error, StackTrace stackTrace) {
    print('${bloc.runtimeType} $error $stackTrace');
    super.onError(bloc, error, stackTrace);
  }
  @override
  void onEvent(Bloc bloc, Object? event) {
    super.onEvent(bloc, event);
    print('${bloc.runtimeType} $event');
  }
  @override
  void onError(Object error, StackTrace stackTrace) {
    print('$error, $stackTrace');
    super.onError(error, stackTrace);
  }
}


Future<void> main() async {
    BlocOverrides.runZoned(
    () {
	    CounterBloc()
	        ..add(CounterIncrementPressed())
	        ..close();  
    },
    blocObserver: SimpleBlocObserver(),
  );
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值