arrow_backTech Blog
phone_android
phone_androidMobile2026-03-05·6 min read

Flutter BLoC State Management: From Basics to Production

Practical experience using BLoC pattern for complex state management in a smart home app — architecture design, event-driven flows, and testing strategies.

FlutterBLoCDart

BLoC Pattern Overview

BLoC (Business Logic Component) is a Stream-based state management solution in Flutter that separates UI from business logic through event-driven architecture.

We chose BLoC not because it's the simplest, but because it's the most predictable in complex scenarios — every state change has a clear source and destination.

Compared to Provider, Riverpod, and GetX, BLoC's advantages are: strict unidirectional data flow, native event sourcing support, and test-friendliness. The trade-off is more boilerplate, but code generation tools significantly mitigate this.

Application in Smart Home Project

Our smart home app manages 30+ device types, each with different states and control methods. Users can create "scenes" for one-tap multi-device control. This complexity made simple setState and Provider unmaintainable.

Device State Management

Each smart device maps to a Cubit/Bloc, using Streams to monitor device state changes in real-time.

  • Light BlocManages brightness, color temperature, on/off state — responds to slider and button events
  • AC BlocTemperature, mode (cooling/heating/dehumidify), fan speed, with scheduled shutdown support
  • Sensor CubitRead-only state (temperature, humidity, PM2.5) — updated via MQTT push
  • Door Lock BlocStatus query + remote unlock + password management — requires additional security checks
  • 💡

    For devices with only state and no complex events (like sensors), Cubit is cleaner than Bloc. Cubit skips Event class definitions and changes state directly via method calls.

    Scene Automation

    MultiBlocProvider combines multiple device Blocs to implement one-tap scene switching like "Home Mode" and "Sleep Mode".

    Scene execution flow:

    1
    User triggers sceneTaps "Home Mode" button
    2
    SceneBloc receives eventParses scene config, gets device list
    3
    Batch commandsRepository dispatches control events to each device Bloc
    4
    State syncEach device Bloc updates state, UI responds automatically
    The biggest challenge in scene automation isn't the technical implementation — it's state consistency. If one device fails, do you rollback others or partial-execute? We chose "best-effort execution + failure notification."

    Key Techniques

    Immutable State

    Use `freezed` for immutable state classes to reduce bugs. Every state change creates a new state object, ensuring traceability.

    Unit Testing

    Write unit tests with `bloc_test` to verify state transitions. BLoC testing is intuitive: given initial state → trigger event → verify output state sequence.

    Granularity Control

    Split Bloc granularity wisely to avoid monolithic Blocs. Our rule: one Bloc manages one "concern," not one page.

  • Anti-patternSingle HomePageBloc managing all homepage state
  • RecommendedDeviceListBloc + SceneBloc + WeatherCubit, each with clear responsibility
  • Error Handling

    Unified error strategy — catch exceptions in Blocs, convert to Error states, UI layer shows appropriate error messages. Avoid try-catch in UI code.


    Project Structure

    After multiple refactors, our settled directory structure:

  • bloc/All Bloc/Cubit definitions
  • models/Data models (using freezed)
  • repositories/Data layer abstraction (API calls, local cache)
  • ui/Pure UI components, connected via BlocBuilder/BlocListener
  • Good architecture lets new team members know where to write code on day one. BLoC's layered constraints provide exactly that clarity.

    Conclusion

    BLoC isn't a silver bullet, but for complex state management, its predictability and testability far exceed alternatives. After launch, state-related bugs decreased ~60%, and new device type integration time dropped from 3 days to 1 day.

    💡

    If your Flutter project has simple state logic, Provider or Riverpod may be better fits. But for complex async flows, multi-device coordination, or strict test coverage needs, BLoC is worth the investment.

    phone_android