Flutter 상태관리 (Bloc - bloc)

2022. 6. 21. 00:00Flutter

반응형

bloc (event 및 state 관리)

: 블록은 함수가 아닌 상태 변경을 트리거하기 위해 이벤트에 의존하는 고급 클래스

Bloc은 또한 BlocBase를 확장하여 Cubit과 유사한 공개 API를 가지고 있다. 

그러나 블록에서 함수를 호출하고 새 상태를 직접 내보내는 대신 

블록은 이벤트를 수신하고 들어오는 이벤트를 나가는 상태로 변환

cubit 과 다른점은 event 를 추적 가능하다는 것

 

 

dartpad.dev 로 이동해서 다음을 코딩하자

 

Counter 이벤트 생성

abstract class CounterEvent {}

Counter 이벤트 확장 (CounterIncrementPressed)

class CounterIncrementPressed extends CounterEvent {}

bloc 생성

class CounterBloc extends Bloc<CounterEvent, int> {
  CounterBloc() : super(0);
}

bloc 에 상태 변경 추가

class CounterBloc extends Bloc<CounterEvent, int> {
  CounterBloc() : super(0) {
    on<CounterIncrementPressed>((event, emit) {
      // handle incoming `CounterIncrementPressed` event
      emit(state + 1);
    });
  }
}

기본사용법 (Future 이용)

Future<void> main() async {
  final bloc = CounterBloc();
  print(bloc.state); // 0
  bloc.add(CounterIncrementPressed());
  await Future.delayed(Duration.zero);
  print(bloc.state); // 1
  await bloc.close();
}

Stream 을 이용한 구독

// stream 이용한 구독
Future<void> main() async {
  final bloc = CounterBloc();
  final subscription = bloc.stream.listen(print); // 1
  bloc.add(CounterIncrementPressed());
  bloc.add(CounterIncrementPressed());
  bloc.add(CounterIncrementPressed());
  bloc.add(CounterIncrementPresed());
  await Future.delayed(Duration.zero);
  await subscription.cancel();
  await bloc.close();
}
// cubit 처럼 관찰 가능
// bloc 관찰
class CounterBloc extends Bloc<CounterEvent, int> {
  CounterBloc() : super(0) {
    on<CounterIncrementPressed>((event, emit) => emit(state + 1));
  }

  @override
  void onChange(Change<int> change) {
    super.onChange(change);
    print(change);
  }
}

 

 

실행

 

cubit 과 다른 점은 event 기반이기 때문에

bloc 의 상태 변경은 촉발한 원인을 캡처(추적) 가능 하다는 것 (onTransition)

abstract class CounterEvent {}

class CounterIncrementPressed extends CounterEvent {}

class CounterBloc extends Bloc<CounterEvent, int> {
  CounterBloc() : super(0) {
    on<CounterIncrementPressed>((event, emit) => emit(state + 1));
  }

  @override
  void onChange(Change<int> change) {
    print(change);
    super.onChange(change);
  }

  @override
  void onTransition(Transition<CounterEvent, int> transition) {
    print(transition);
    super.onTransition(transition);
  }
}

실행

Transition { currentState: 0, event: Instance of 'CounterIncrementPressed', nextState: 1 }
Change { currentState: 0, nextState: 1 }
1
Transition { currentState: 1, event: Instance of 'CounterIncrementPressed', nextState: 2 }
Change { currentState: 1, nextState: 2 }
2
Transition { currentState: 2, event: Instance of 'CounterIncrementPressed', nextState: 3 }
Change { currentState: 2, nextState: 3 }
3
Transition { currentState: 3, event: Instance of 'CounterIncrementPressed', nextState: 4 }
Change { currentState: 3, nextState: 4 }
4

블록 옵저버 (BlocObserver)

:  bloc 의 모든 변경 내용을 관찰 하기 위한 class (cubit 와 마찬가지)

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

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

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

void main() {
  BlocOverrides.runZoned(
    () {
      CounterBloc()
        ..add(CounterIncrementPressed())
        ..close();
    },
    blocObserver: SimpleBlocObserver(),
  );
}

실행

 

onEvent 를 통한 이벤트 추적

class CounterBloc extends Bloc<CounterEvent, int> {
...
void onEvent(CounterEvent event) {
    print(event);
    super.onEvent(event);
  }
...
}
class SimpleBlocObserver extends BlocObserver {
  @override
  void onEvent(Bloc bloc, Object? event) {
    print('${bloc.runtimeType} $event');
    super.onEvent(bloc, event);
  }
...
}

실행

 

Cubit vs Bloc

 

Cubit 장점

간편함

같은 기능을 구현 하는 Bloc 에 비해 간편하다. 

 

Bloc 장점

추적성

상태 변경의 순서와 이러한 변경을 촉발한 정확한 원인을 알 수 있다는 것 (Transition)

 

 

관련영상

https://youtu.be/3GzXX4Mv4Dw

 

 

반응형