BLoC — wat is het, Business Logic Component in Flutter

Auteur: IT Sectr Gepubliceerd: 2026-02-19 Leestijd: 7 min

BLoC (Business Logic Component) — patroon voor statusbeheer voor Flutter, gepresenteerd door Google in 2018 op DartConf. BLoC scheidt bedrijfslogica van de gebruikersinterface via reactieve stromen (Stream): UI verzendt een Event, BLoC verwerkt het en retourneert een nieuwe State via Stream. Volgens gegevens van pub.dev heeft het flutter_bloc-pakket meer dan 11 duizend likes verzameld en wordt het gebruikt in duizenden Flutter-applicaties.

Belangrijkste punten

  • Event — ingangssignaal dat de actie beschrijft: knopdruk, gegevens laden
  • State — uitgangstoestand van UI: gegevens geladen, fout, laden
  • Bloc — hoofdklasse die Event ontvangt en State retourneert via Stream
  • Cubit — vereenvoudigde versie van Bloc zonder Event, roept functies direct aan
  • BlocProvider — Flutter widget voor injectie van Bloc in de widgetboom

Wat is BLoC?

BLoC (Business Logic Component) — architectuurpatroon voor Flutter waarin bedrijfslogica is ondergebracht in een aparte klasse, geïsoleerd van de UI. BLoC ontvangt invoergegevens via een stroom van gebeurtenissen (Event) en produceert uitvoergegevens via een stroom van toestanden (State). De presentatielaag (Widget) abonneert zich alleen op de State-stroom en geeft de UI weer, zonder ooit direct bedrijfslogica uit te voeren.

Het BLoC-concept is gebaseerd op reactief programmeren en het Observer-patroon. Elk BLoC-component is een aparte module met een duidelijk contract: de set Event (wat kan er gebeuren) en de set State (wat kan worden weergegeven) zijn bekend. De ontwikkelaar kan niet "per ongeluk" de status vanuit de UI wijzigen — alleen via een specifiek Event. Dit maakt de code voorspelbaar en testbaar.

Volgens de Flutter Community 2025-enquête staat BLoC op de tweede plaats in populariteit onder oplossingen voor statusbeheer in Flutter na Provider. Belangrijkste voordelen: strikte typering, isolatie van logica, ingebouwde ondersteuning voor Stream, rijk ecosysteem van hulpprogramma's (BlocProvider, BlocListener, BlocSelector).

BLoC architectuur: Event → Bloc → State

BLoC architectuur is gebouwd rond drie entiteiten: Event (ingang), Bloc (verwerker) en State (uitgang). Widget verzendt een Event via de methode add(). Bloc ontvangt het Event in de methode mapEventToState of on<Event>, voert bedrijfslogica uit en produceert een nieuwe State via yield. Widget ontvangt de State via Stream en wordt opnieuw getekend.

Dart
abstract class CounterEvent {}

class Increment extends CounterEvent {}
class Decrement extends CounterEvent {}

class CounterBloc extends Bloc<CounterEvent, int> {
  CounterBloc() : super(0);

  @override
  Stream<int> mapEventToState(CounterEvent event) async* {
    if (event is Increment) {
      yield state + 1;
    } else if (event is Decrement) {
      yield state - 1;
    }
  }
}

Typeveiligheid: Bloc is geparametriseerd met twee typen — Event en State. De Dart-compiler controleert of Widget alleen gedeclareerde Events aanroept en Bloc alleen gedeclareerde States retourneert. Uitvoeringsfouten van het type "Onbekende Actie" zijn uitgesloten.

Close en Dispose: Bloc implementeert de interface Closeable. Bij vernietiging van de widget sluit Bloc automatisch de Stream via de methode close(). Lekken van reactieve abonnementen zijn onmogelijk — BlocProvider beheert de levenscyclus van Bloc en koppelt deze aan een route of pagina.

Bloc en Cubit: vergelijking

Cubit — vereenvoudigde implementatie van Bloc zonder Event, geïntroduceerd in het flutter_bloc 6.0-pakket. Cubit declareert methoden direct in plaats van Event-klassen: increment(), fetchData(). Intern gebruikt Cubit hetzelfde Stream-gebaseerde mechanisme, maar verbergt de Event-laag. Dit vermindert boilerplate met 40-50% voor eenvoudige scenario's.

KenmerkBlocCubit
Event-klassenVerplichtNiet nodig
BoilerplateHoogLaag
Acties volgenVia Event-typeAlleen methode naam
Geschikt voorComplexe scenario'sEenvoudige toestanden
AnalyseAutomatisch via EventHandmatig

Wanneer Cubit kiezen: toestand met 2-3 varianten (loading, loaded, error), eenvoudige formulieren, tellers, UI-toestanden (open/gesloten). Wanneer Bloc: complexe bedrijfslogica met meerdere acties: bestelling plaatsen, autorisatie, gegevenssynchronisatie. Bloc biedt gedetailleerde traceerbaarheid van elke actie via Event — elke aanroep wordt geregistreerd in BlocObserver.

BlocObserver — wereldwijde waarnemer die alle Bloc en Cubit in de applicatie volgt. Maakt het mogelijk om Event, State, fouten en overgangen te loggen. Het is voldoende om één exemplaar aan te sluiten: Bloc.observer = AppBlocObserver(), en de volledige toestandstracering van de applicatie is centraal beschikbaar.

BlocProvider en BlocBuilder

BlocProvider — InheritedWidget uit flutter_bloc dat Bloc beschikbaar stelt aan onderliggende widgets. Bij initialisatie van de widget maakt BlocProvider een Bloc aan, en bij vernietiging — wordt deze automatisch gesloten via close(). BlocProvider kan op MaterialApp-niveau (globale Bloc) of op het niveau van een specifieke route (lokale Bloc) worden geplaatst.

Dart
BlocProvider(
  create: (context) => CounterBloc(),
  child: Column(
    children: [
      BlocBuilder<CounterBloc, int>(
        builder: (context, state) => Text('$state'),
      ),
      ElevatedButton(
        onPressed: () => context.read<CounterBloc>().add(Increment()),
        child: Text('+'),
      ),
    ],
  ),
)

BlocBuilder — widget die de UI herbouwt bij elke nieuwe State. BlocListener — voor bijwerkingen (eenmalige verwerking van State zonder UI-herbouw): SnackBar tonen, navigeren naar een ander scherm. BlocConsumer — combinatie van Builder en Listener voor gevallen waarin zowel herbouw als bijwerking nodig is. BlocSelector — voor selectieve herbouw alleen bij wijziging van een specifiek veld van State.

MultiBlocProvider — widget voor geneste BlocProviders zonder de nestdiepte te vergroten. Een Flutter-applicatie met 10-15 Bloc gebruikt MultiBlocProvider op hoofdniveau voor registratie van alle Bloc die beschikbaar zijn voor de hele applicatie: AuthenticationBloc, CartBloc, SettingsBloc.

BLoC testen

BLoC wordt getest geïsoleerd zonder Flutter-widgets. Het is voldoende om het Dart-pakket flutter_test en het pakket bloc_test te importeren. Testscenario: een Bloc maken, een Event toevoegen, State controleren. blocTest — hulpprogramma dat de volgorde build → act → expect automatiseert.

Dart
blocTest<CounterBloc, int>(
  'emits [1] when Increment is added',
  build: () => CounterBloc(),
  act: (bloc) => bloc.add(Increment()),
  expect: () => [1],
)

Mocking: BLoC dat afhankelijk is van een repository of API wordt getest met mocks via mocktail. De repository wordt gemockt op abstractieniveau, Bloc ontvangt gemockte afhankelijkheden via de constructor. Hydrated Bloc — extensie voor automatisch opslaan/herstellen van status in lokale opslag. Wordt getest met HydratedBlocStorage en tijdelijke bestandsopslag.

BLoC in productie

Mappen en bestanden: typische structuur van een Flutter-project met BLoC: bloc/counter_bloc.dart, bloc/counter_event.dart, bloc/counter_state.dart. Voor 30+ schermen wordt groepering op functionaliteit aanbevolen: features/auth/bloc/, features/cart/bloc/. Elke Bloc — apart bestand, elke Event en State — ofwel in aparte bestanden, ofwel in één bestand met Bloc.

Prestaties: BLoC creëert geen overhead op lege Streams. BlocBuilder gebruikt buildWhen voor het filteren van herbouwen — de widget wordt alleen bijgewerkt wanneer een specifieke voorwaarde verandert. Close garandeert dat inactieve Bloc geen geheugen verbruiken. Volgens Flutter DevTools voegt BLoC minder dan 1% toe aan de bundelgrootte.

Migratie van Provider: BLoC kan gemakkelijk samen met Provider in hetzelfde project bestaan. Gefaseerde migratie: eerst worden de meest complexe Providers vervangen door Bloc, daarna de rest. BlocProvider is compatibel met de Provider-boom: oude widgets kunnen Provider gebruiken, nieuwe — BlocProvider, in dezelfde applicatie.

Veelgestelde vragen

Wat is het verschil tussen BLoC en Provider in Flutter?

BLoC gebruikt Event + Stream voor isolatie van bedrijfslogica en strikte typering. Provider — een wrapper rond InheritedWidget voor eenvoudige dependency-injectie en ChangeNotifier. BLoC is beter geschikt voor complexe scenario's met meerdere toestanden, Provider — voor lokale UI-status. BLoC vereist meer boilerplate, maar biedt volledige traceerbaarheid via Event.

Wat is Hydrated Bloc?

Hydrated Bloc — extensie uit het hydrated_bloc-pakket dat automatisch de laatste State opslaat in lokale opslag (standaard Hive). Bij herstart van de applicatie herstelt Bloc de opgeslagen toestand in plaats van de beginstatus. Dit lost het persistentieprobleem op zonder handmatige opslagaanroep: login, winkelwagen, instellingen worden automatisch opgeslagen tussen sessies.

Hoe fouten afhandelen in BLoC?

Een fout in BLoC wordt afgehandeld via try-catch binnen mapEventToState of on<Event>. Bij een fout retourneert Bloc een fout-State: yield LoadError(error.message). In de UI controleert BlocListener of BlocConsumer de State op het fouttype en toont een SnackBar of dialoog. BlocObserver logt globaal alle onverwerkte uitzonderingen.

Kan BLoC met andere frameworks worden gebruikt?

BLoC — Flutter-specifiek patroon, omdat het Dart Stream en Flutter-widgets gebruikt. Het concept Event → Bloc → State kan worden aangepast voor AngularDart en Server-side Dart, maar het belangrijkste ecosysteem (BlocProvider, BlocBuilder, BlocObserver) is gekoppeld aan Flutter. Gebruik voor React Native Redux of MobX, voor SwiftUI — Combine + MVVM.

Wat kiezen: Bloc of Cubit?

Cubit — voor eenvoudige toestanden (teller, toggle, formulier met 2-3 velden). Bloc — voor complexe logica (nieuwsfeed, bestelling plaatsen, autorisatie). Hoofdregel: als tracering van elke actie (Event) nodig is voor analyse of debugging — Bloc. Als methoden die de status wijzigen voldoende zijn — Cubit. Beide patronen kunnen in hetzelfde project naast elkaar bestaan.

Samenvatting

  • BLoC — patroon voor statusbeheer in Flutter via Event → Stream → State
  • Event — actie (klik, laden), State — reactie (gegevens, fout, laden)
  • Cubit — vereenvoudigde versie zonder Event, tot 50% minder boilerplate
  • BlocProvider — injectie van Bloc in de widgetboom met automatische close
  • BlocObserver — wereldwijde monitoring van alle Bloc en Cubit in de applicatie
  • Hydrated Bloc — automatische persistentie van status via Hive
  • blocTest — hulpprogramma voor modulair testen van Bloc met isolatie van Flutter

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook