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의 경우 중복된 것은 무시됩니다.
중복 검사는 단순하게 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];
}
props
리스트에 선언된 변수들도 단순하게 previousState.props[0] == nextState.props[0]
이런식으로 판단하기 때문에 비교 가능한 변수가 있어야 합니다.