Agent Skills: BLoC State Management

Implement BLoC/Cubit state management correctly in Flutter. Use when writing, modifying, reviewing, or testing any BLoC, Cubit, state, or event Dart file — even for small changes. (triggers: **_bloc.dart, **_cubit.dart, **_state.dart, **_event.dart, BlocProvider, BlocBuilder, BlocListener, Cubit, Emitter)

UncategorizedID: hoangnguyen0403/agent-skills-standard/flutter-bloc-state-management

Install this agent skill to your local

pnpm dlx add-skill https://github.com/HoangNguyen0403/agent-skills-standard/tree/HEAD/skills/flutter/flutter-bloc-state-management

Skill Files

Browse the full folder contents for flutter-bloc-state-management.

Download Skill

Loading file tree…

skills/flutter/flutter-bloc-state-management/SKILL.md

Skill Metadata

Name
flutter-bloc-state-management
Description
"Implement BLoC/Cubit state management correctly in Flutter. Use when writing, modifying, reviewing, or testing any BLoC, Cubit, state, or event Dart file — even for small changes. (triggers: **_bloc.dart, **_cubit.dart, **_state.dart, **_event.dart, BlocProvider, BlocBuilder, BlocListener, Cubit, Emitter)"

BLoC State Management

Priority: P0 (CRITICAL)

You are a Flutter State Management Expert. Design predictable, testable state flows.

State Design Workflow

  1. Define Events: What happens? (UserTap, ApiSuccess). Use @freezed.
  2. Define States: What needs to show? (Initial, Loading, Data, Error).
  3. Implement BLoC: Map Events to States using on<Event>.
  4. Connect UI: Use BlocBuilder for rebuilds, BlocListener for side effects.

Implementation Guidelines

  • States & Events: Use @freezed for union types (e.g., Initial, Loading, Success, Failure states).
  • Error Handling: Emit Failure states for UI-critical errors. For silent/background events, either let exceptions propagate naturally to the global onError interceptor (e.g., in AppBlocObserver), or catch and call addError(e, st) without emitting an error state.
  • Async Data: Use emit.forEach for streams or await with emit call.
  • Concurrency: Use transformer: restartable() from bloc_concurrency for search/typeahead to debounce and cancel previous requests.
  • UI Connectivity: Use BlocBuilder for UI rebuilds (e.g., loading spinner, data list, error message) and BlocListener for side effects (navigation, snackbars).
  • Testing: Use blocTest for ALL states and verify the sequence of emitted states.

Verification Checklist (Mandatory)

  • [ ] Initial State: Defined and tested?
  • [ ] Test Coverage: blocTest used for ALL states?
  • [ ] UI Logic: No complex calculation in BlocBuilder?
  • [ ] Side Effects: Navigation/Snackbars in BlocListener (NOT Builder)?

Anti-Patterns

  • No .then(): Use await or emit.forEach() to emit.
  • No BLoC-to-BLoC: Use StreamSubscription or BlocListener, not direct refs.
  • No Logic in Builder: Move valid logic to BLoC.
  • No BlocBuilder wrapping expensive subtrees without buildWhen: Every BlocBuilder that contains heavy child widgets (cards, lists, sections) MUST declare a buildWhen predicate narrowing rebuilds to the specific state fields it depends on. Omitting buildWhen causes the entire subtree to rebuild on every state emission, regardless of relevance.

References