BLoC State Management
Priority: P0 (CRITICAL)
Predictable state management separating business logic from UI using bloc, freezed, or equatable.
Structure
presentation/blocs/
├── auth/
│ ├── auth_bloc.dart
│ ├── auth_event.dart # (@freezed or Equatable)
│ └── auth_state.dart # (@freezed or Equatable)
Implementation Guidelines
- States & Events: Default to
@freezed(Priority). UseEquatableif the library is present inpubspec.yaml.- freezed: Use for union states (initial, loading, success) and automatic
copyWith. - Equatable: Apply if code generation (build_runner) is avoided or
equatableis the only comparison library inpubspec.yaml. - Choose strategy:
- Union State: Exclusive UI phases (loading vs data).
- Property-based State: Complex forms (Option<$Either>, flags).
- freezed: Use for union states (initial, loading, success) and automatic
- State Properties: Use enums, sealed classes, or
Statusobjects. - Error Handling: Use
Failureobjects; avoid throwing exceptions. - Async Data: Use
emit.forEachoremit.onEachfor streams. - Concurrency: Use
transformer(restartable, droppable) for event debouncing. - Testing: Use
blocTestfor state transition verification. - Injection: Register BLoCs as
@injectable(Factory).
Anti-Patterns
- No Manual Emit: Do not call
emit()insideFuture.then; always useawaitoremit.forEach. - No UI Logic: Do not perform calculations or data formatting inside
BlocBuilder. - No Cross-Bloc Reference: Do not pass a BLoC instance into another BLoC; use streams or the UI layer to coordinate.
Reference & Examples
For full BLoC/Cubit implementations and concurrency patterns: See references/REFERENCE.md.
Related Topics
feature-based-clean-architecture | dependency-injection