BLoC — o que é, Business Logic Component no Flutter

Autor: IT Sectr Publicado: 2026-02-19 Tempo de leitura: 7 min

BLoC (Business Logic Component) — um padrão de gerenciamento de estado para Flutter, apresentado pelo Google em 2018 no DartConf. BLoC separa a lógica de negócio da interface do usuário através de fluxos reativos (Stream): a UI envia um Event, o BLoC processa e retorna um novo State através do Stream. De acordo com pub.dev, o pacote flutter_bloc acumulou mais de 11 mil curtidas e é usado em milhares de aplicações Flutter.

Principais pontos

  • Event — sinal de entrada que descreve uma ação: pressionar botão, carregar dados
  • State — estado de saída da UI: dados carregados, erro, carregando
  • Bloc — classe principal que recebe Event e retorna State via Stream
  • Cubit — versão simplificada do Bloc sem Event, chamando funções diretamente
  • BlocProvider — widget Flutter para injetar Bloc na árvore de widgets

O que é BLoC?

BLoC (Business Logic Component) — um padrão arquitetural para Flutter no qual a lógica de negócio é extraída para uma classe separada, isolada da UI. BLoC recebe dados de entrada através de um fluxo de eventos (Event) e produz dados de saída através de um fluxo de estados (State). A camada de apresentação (Widget) apenas se inscreve no fluxo de State e renderiza a UI, nunca executando a lógica de negócio diretamente.

O conceito BLoC é baseado em programação reativa e no padrão Observer. Cada componente BLoC é um módulo separado com um contrato claro: um conjunto conhecido de Events (o que pode acontecer) e um conjunto conhecido de States (o que pode ser exibido). Um desenvolvedor não pode "acidentalmente" alterar o estado da UI — apenas através de um Event específico. Isso torna o código previsível e testável.

De acordo com a pesquisa Flutter Community 2025, BLoC ocupa o segundo lugar em popularidade entre as soluções de gerenciamento de estado no Flutter, depois do Provider. Principais vantagens: tipagem forte, isolamento de lógica, suporte nativo a Stream, ecossistema rico de utilitários (BlocProvider, BlocListener, BlocSelector).

Arquitetura BLoC: Event → Bloc → State

A arquitetura BLoC é construída em torno de três entidades: Event (entrada), Bloc (processador) e State (saída). O Widget envia um Event através do método add(). O Bloc recebe o Event no método mapEventToState ou on<Event>, executa a lógica de negócio e emite um novo State via yield. O Widget recebe o State através de um Stream e reconstrói.

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;
    }
  }
}

Segurança de tipos: Bloc é parametrizado com dois tipos — Event e State. O compilador Dart verifica se o Widget chama apenas Events declarados e se o Bloc retorna apenas States declarados. Erros de tempo de execução como "Action desconhecida" são eliminados.

Close e Dispose: Bloc implementa a interface Closeable. Quando um widget é destruído, o Bloc fecha automaticamente o Stream através do método close(). Vazamentos de assinaturas reativas são impossíveis — BlocProvider gerencia o ciclo de vida do Bloc, vinculando-o a uma rota ou página.

Bloc e Cubit: comparação

Cubit é uma implementação simplificada do Bloc sem Event, apresentada no pacote flutter_bloc 6.0. Cubit declara métodos diretamente em vez de classes Event: increment(), fetchData(). Internamente, Cubit usa o mesmo mecanismo baseado em Stream, mas oculta a camada de Event. Isso reduz o boilerplate em 40-50% para cenários simples.

CaracterísticaBlocCubit
Classes EventObrigatóriasNão necessárias
BoilerplateAltoBaixo
Rastreamento de açõesVia tipo EventApenas nome do método
Ideal paraCenários complexosEstados simples
AnalíticaAutomática por EventManual

Quando escolher Cubit: estado com 2-3 variantes (loading, loaded, error), formulários simples, contadores, estados de UI (aberto/fechado). Quando escolher Bloc: lógica de negócio complexa com múltiplas ações: processamento de pedidos, autorização, sincronização de dados. Bloc fornece rastreamento detalhado de cada ação através de Event — cada chamada é registrada no BlocObserver.

BlocObserver — um observador global que rastreia todos os Bloc e Cubit na aplicação. Permite registrar Event, State, erros e transições. Basta conectar uma instância: Bloc.observer = AppBlocObserver(), e todo o rastreamento de estado da aplicação fica disponível centralizadamente.

BlocProvider e BlocBuilder

BlocProvider — um InheritedWidget do flutter_bloc que fornece um Bloc aos widgets filhos. Quando um widget é inicializado, BlocProvider cria um Bloc, e quando destruído — fecha automaticamente via close(). BlocProvider pode ser colocado no nível do MaterialApp (Bloc global) ou no nível de uma rota específica (Bloc local).

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 — um widget que reconstrói a UI a cada novo State. BlocListener — para efeitos colaterais (processar um State uma vez, sem reconstruir a UI): mostrar um SnackBar, navegar para outra tela. BlocConsumer — uma combinação de Builder e Listener para casos onde são necessários tanto reconstrução quanto efeito colateral. BlocSelector — para reconstrução seletiva apenas quando um campo específico do State muda.

MultiBlocProvider — um widget para BlocProviders aninhados sem aumentar níveis de aninhamento. Uma aplicação Flutter com 10-15 Blocs usa MultiBlocProvider no nível raiz para registrar todos os Blocs disponíveis para toda a aplicação: AuthenticationBloc, CartBloc, SettingsBloc.

Testando BLoC

BLoC é testado isoladamente sem widgets Flutter. Basta importar o pacote Dart flutter_test e o pacote bloc_test. O cenário de teste: criar um Bloc, adicionar um Event, verificar o State. blocTest — um utilitário que automatiza a sequência: build → act → expect.

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

Mocking: Um Bloc que depende de um repositório ou API é testado com mocks via mocktail. O repositório é simulado no nível de abstração, e o Bloc recebe as dependências simuladas através do construtor. Hydrated Bloc — uma extensão para persistência/restauração automática de estado em armazenamento local. É testado com HydratedBlocStorage e armazenamento de arquivo temporário.

BLoC em produção

Pastas e arquivos: uma estrutura típica de projeto Flutter com BLoC: bloc/counter_bloc.dart, bloc/counter_event.dart, bloc/counter_state.dart. Para 30+ telas, recomenda-se agrupamento por funcionalidades: features/auth/bloc/, features/cart/bloc/. Cada Bloc é um arquivo separado, cada Event e State — seja em arquivos separados ou em um arquivo com o Bloc.

Desempenho: BLoC não cria sobrecarga para Streams vazios. BlocBuilder usa buildWhen para filtrar reconstruções — o widget só atualiza quando uma condição específica muda. Close garante que Blocs inativos não consumam memória. De acordo com Flutter DevTools, BLoC adiciona menos de 1% ao tamanho do bundle.

Migração do Provider: BLoC coexiste facilmente com Provider no mesmo projeto. Migração gradual: primeiro substitua os Providers mais complexos por Bloc, depois o restante. BlocProvider é compatível com a árvore Provider: widgets antigos podem usar Provider, novos — BlocProvider, dentro de uma única aplicação.

Perguntas frequentes

Como BLoC é diferente do Provider no Flutter?

BLoC usa Event + Stream para isolamento da lógica de negócio e tipagem forte. Provider é um wrapper em torno de InheritedWidget para injeção simples de dependência e ChangeNotifier. BLoC é melhor para cenários complexos com múltiplos estados, Provider — para estado de UI local. BLoC requer mais boilerplate, mas fornece rastreabilidade completa através de Events.

O que é Hydrated Bloc?

Hydrated Bloc é uma extensão do pacote hydrated_bloc que salva automaticamente o último State no armazenamento local (Hive por padrão). Quando a aplicação reinicia, o Bloc restaura o estado salvo em vez do inicial. Isso resolve o problema de persistência sem chamadas manuais de salvamento: login, carrinho, configurações são salvos automaticamente entre sessões.

Como lidar com erros no BLoC?

Um erro no BLoC é tratado através de try-catch dentro de mapEventToState ou on<Event>. Em caso de erro, Bloc retorna um State de erro: yield LoadError(error.message). Na UI, BlocListener ou BlocConsumer verifica o State pelo tipo de erro e mostra um SnackBar ou diálogo. BlocObserver registra globalmente todas as exceções não tratadas.

BLoC pode ser usado com outros frameworks?

BLoC é um padrão específico do Flutter, pois usa Dart Stream e widgets Flutter. O conceito Event → Bloc → State pode ser adaptado para AngularDart e Server-side Dart, mas o ecossistema principal (BlocProvider, BlocBuilder, BlocObserver) está vinculado ao Flutter. Para React Native, use Redux ou MobX; para SwiftUI, use Combine + MVVM.

O que escolher: Bloc ou Cubit?

Cubit — para estados simples (contador, toggle, formulário com 2-3 campos). Bloc — para lógica complexa (feed de notícias, processamento de pedidos, autorização). A regra principal: se você precisa de rastreamento de cada ação (Event) para análise ou depuração — escolha Bloc. Se métodos que mudam o estado são suficientes — escolha Cubit. Ambos os padrões podem coexistir no mesmo projeto.

Resumo

  • BLoC — padrão de gerenciamento de estado Flutter via Event → Stream → State
  • Event — ação (pressionar, carregar), State — reação (dados, erro, carregando)
  • Cubit — versão simplificada sem Event, até 50% menos boilerplate
  • BlocProvider — injeção de Bloc na árvore de widgets com fechamento automático
  • BlocObserver — monitoramento global de todos os Bloc e Cubit na aplicação
  • Hydrated Bloc — persistência automática de estado via Hive
  • blocTest — utilitário para teste unitário de Bloc isolado do Flutter

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também