Skip to main content

Bloc Event to State


  • flutter_bloc: 7.0.0
  • equatable: 2.0.0

Event

Event 명은 Bloc 명 + (수식할 명사) 요청사항(과거 동사)으로 구성하는 것을 추천하지만 헷갈리지 않는다면 어떻게 작성하든 상관 없습니다.

Event는 enum 또는 class로 정의 할 수 있습니다. Event가 단순한 경우 enum으로 정의하는 것이 좋습니다.

예를 들어 단순한 컨트롤러와 관련된 Event를 만든다면 아래와 같이 구성할 수 있습니다.

part of 'controller_bloc.dart';

enum ControllerEvent { fanOnRequested, fanOffRequested }

하지만 선풍기의 풍속이나 방향 등을 조절하기 위해 Event와 함께 설정 값을 알려줘야한다면, class로 정의하는 것이 좋습니다.

part of 'controller_bloc.dart';

abstract class ControllerEvent {
const ControllerEvent();
}

class ControllerFanRequested extends ControllerEvent {
final bool autoRotation;
final double strength;

const ControllerFanRequested.on(
{this.autoRotation = false, this.strength = 0.5});

const ControllerFanRequested.off()
: autoRotation = false,
strength = 0;

const ControllerFanRequested.startAutoRotation({this.strength = -1})
: autoRotation = true;

const ControllerFanRequested.stopAutoRotation({this.strength = -1})
: autoRotation = false;
}

State

State 명은 Bloc 명 + 취한 행동(동사) + 상태로 구성하는 것을 추천하지만 헷갈리지 않는다면 어떻게 작성하든 상관 없습니다.

Event와 마찬가지로 enum 또는 class로 정의할 수 있지만, 불필요한 렌더링을 막기 위해 State의 경우 중복된 것은 무시됩니다.

info

중복 검사는 단순하게 previousState == nextState가 참인지 아닌지만 판단합니다.

part of 'controller_bloc.dart';

enum ControllerState {
fanOnRequestSuccess,
fanOnRequestFailure,
fanOffRequestSuccess,
fanOffRequestFailure,
}

State가 같더라도 presentation layer를 갱신하길 원하는 경우 enum은 사용할 수 없습니다. 이런 경우 class로 만들고, 항상 새로 생성해야합니다. 같은 class라도 새로 생성된 객체는 다르다고 판단하기 때문입니다.

part of 'controller_bloc.dart';

enum ControllerRequestStatus { success, failure }

abstract class ControllerState {
const ControllerState();
}

class ControllerInitial extends ControllerState {}

class ControllerFanRequestState extends ControllerState {
final ControllerRequestStatus status;
final bool autoRotation;
final double strength;

const ControllerFanRequestState.failure()
: status = ControllerRequestStatus.failure,
autoRotation = false,
strength = 0;

const ControllerFanRequestState.success(this.autoRotation, this.strength)
: status = ControllerRequestStatus.success;
}

많은 상황에서 중복된 State 처리를 할 필요가 없습니다. 따라서 class를 사용하더라도, 중복된 값인지 확인할 방법이 필요합니다. Equatable을 상속하여 Event를 만들고, props를 오버라이드 하여 Event의 타입과 porps에 선언된 데이터가 같다면 중복으로 판단할 수 있도록 해야합니다.

part of 'controller_bloc.dart';

enum ControllerRequestStatus { success, failure }

abstract class ControllerState extends Equatable {
const ControllerState();
}

class ControllerInitial extends ControllerState {

List<Object?> get props => [];
}

class ControllerFanRequestState extends ControllerState {
final ControllerRequestStatus status;
final bool autoRotation;
final double strength;

const ControllerFanRequestState.failure()
: status = ControllerRequestStatus.failure,
autoRotation = false,
strength = 0;

const ControllerFanRequestState.success(this.autoRotation, this.strength)
: status = ControllerRequestStatus.success;


List<Object?> get props => [status, autoRotation, strength];
}
info

props 리스트에 선언된 변수들도 단순하게 previousState.props[0] == nextState.props[0] 이런식으로 판단하기 때문에 비교 가능한 변수가 있어야 합니다.

mapEventToState