Intermediate · State management · topic 30 of 50 · 30 min
Bloc, Cubit and choosing an approach
Explanation
What is Bloc?
Bloc stands for Business Logic Component. The flutter_bloc package (documented at bloclibrary.dev) organises logic into classes that take inputs and produce a stream of states. The UI only renders states and sends inputs. This strict separation makes behaviour predictable and very testable, which is why many larger companies and teams choose it.
Cubit: methods in, states out
import 'package:flutter_bloc/flutter_bloc.dart';
class CounterCubit extends Cubit<int> {
CounterCubit() : super(0); // initial state
void increment() => emit(state + 1); // emit a new state
void reset() => emit(0);
}Bloc: events in, states out
sealed class LoginEvent {}
class LoginSubmitted extends LoginEvent {
LoginSubmitted(this.mobile);
final String mobile;
}
sealed class LoginState {}
class LoginInitial extends LoginState {}
class LoginLoading extends LoginState {}
class LoginSuccess extends LoginState {}
class LoginFailure extends LoginState {
LoginFailure(this.message);
final String message;
}
class LoginBloc extends Bloc<LoginEvent, LoginState> {
LoginBloc() : super(LoginInitial()) {
on<LoginSubmitted>((event, emit) async {
emit(LoginLoading());
await Future.delayed(const Duration(seconds: 1)); // pretend API call
if (event.mobile.length == 10) {
emit(LoginSuccess());
} else {
emit(LoginFailure('Enter a valid 10-digit mobile number'));
}
});
}
}Why events? Every change to the state passes through one place and has a name (LoginSubmitted, LogoutPressed). The bloc library can log every event and state transition, which makes bugs easy to trace in big apps, and tests can say "given these events, expect these states" (the bloc_test package helps).
Using them in the UI
BlocProvider(
create: (_) => LoginBloc(),
child: BlocConsumer<LoginBloc, LoginState>(
listener: (context, state) { // one-off reactions
if (state is LoginSuccess) context.go('/home');
if (state is LoginFailure) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(state.message)));
}
},
builder: (context, state) => FilledButton( // rebuilds on every state
onPressed: state is LoginLoading
? null
: () => context.read<LoginBloc>().add(LoginSubmitted('9876543210')),
child: Text(state is LoginLoading ? 'Please wait...' : 'Login'),
),
),
)BlocProvider also closes the Bloc automatically when it leaves the tree, so you do not leak its stream.
Choosing an approach
| Approach | Good for | Trade-offs |
|---|---|---|
| setState | Ephemeral state inside one widget | Does not scale to shared state |
| Provider | Small to medium apps; learning | Run-time errors if a provider is missing; tied to the widget tree |
| Riverpod | Small to large apps wanting compile safety and easy testing | New concepts; APIs evolved across versions |
| Bloc/Cubit | Large apps and teams wanting strict structure and traceable state changes | More boilerplate code |
There is no single "best". Companies pick one and stay consistent; job posts often mention Provider, Riverpod or Bloc by name, so check what your target companies use. Learn one deeply, understand the others at concept level, and be ready to explain why you chose yours.
Common mistakes
- Using three state management libraries in one app.
- Navigating or showing SnackBars inside BlocBuilder's builder: they can repeat on rebuild. Use BlocListener.
- Mutating state objects instead of emitting new ones: equal objects may not trigger rebuilds.
- Choosing Bloc for a tiny app because it "looks professional": the boilerplate slows you down.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Bloc, Cubit and choosing an approach · 1/6
Bloc means business logic component. The UI sends inputs and renders states.
Prefer a video by a teacher? Find free videos on “flutter bloc cubit tutorial blocbuilder bloclistener when to use” on YouTube ↗
In real life: A team decision at a fintech startup
A fintech startup with eight Flutter developers chooses Bloc for its lending app: every state change (application submitted, KYC pending, approved, rejected) is an explicit event and state, easy to log and audit, and each Bloc has unit tests. A two-person agency building restaurant apps chooses Provider for speed and simplicity. Both are right for their context.
Practice (0/3 done)
Where should a SnackBar after a failed login be shown in flutter_bloc?
What is the difference between a Cubit and a Bloc?
Write a CounterCubit and a small screen using BlocProvider and BlocBuilder. Then write down, in a short table, which state management approach you would choose for: a personal expense tracker, a 10-developer banking app, and a medium food delivery app, with one reason each.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- What state is, and setStateState management · same module
- Flutter jobs and freelancing in IndiaFlutter careers and interviews
- Interview questions: FlutterFlutter careers and interviews
- Flow and StateFlowKotlin and Android App Development · Coroutines and Flow
- ViewModel and MVVMKotlin and Android App Development · Navigation and app architecture
- Material componentsKotlin and Android App Development · Permissions, Material 3 and polish
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
What does emit do in a Cubit?
Answer: Publishes a new state to listeners
Listeners rebuild with the new state.
Which widget does both rebuilding and one-off reactions?
Answer: BlocConsumer
Consumer = builder + listener.
Which is a common reason teams choose Bloc?
Answer: Strict separation and traceable, testable state changes
Structure for large teams.
What is good advice about state management choices?
Answer: Pick one, learn it well, use it consistently
Consistency matters most.
What should you do before starting a freelance app project?Related
Answer: Agree a written scope, timeline and payment milestones
Clear scope prevents disputes.
Which object holds a StatefulWidget's State between rebuilds?Related
Which is best for a one-off event like "navigate to the payment screen"?Related
Answer: SharedFlow (or a state that is cleared after handling)
Events should not be replayed like state.
From Flow and StateFlow
What does the ViewModel expose to the UI?Related
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- This is the last topic of “State management”. The module exam comes next.
- Module 7 exam: State management · 12 questions · 25 min, without help. 4 topics of this module still to finish first.
- Then the next module, Networking, storage and Firebase. 50 topics left in the course before the final exam.