Flutter
State classes
Model UI state with state classes.
What are state classes?
State classes are immutable objects that model the current state of the interface. Each distinct UI state is expressed as a separate state class: loading, success, error, and so on. This allows safe state checks like if (state is LoginSuccess).
abstract class LoginState {}
class LoginLoading extends LoginState {}
class LoginSuccess extends LoginState {
final String user;
LoginSuccess(this.user);
}
Abstract state and subclasses
Deriving states from an abstract class groups common behavior and makes state checks safer. When you define every possible state as a separate class, you handle each case individually with switch or if (state is ...). This makes it harder to miss a case and keeps the code readable.
abstract class LoginState {}
class LoginInitial extends LoginState {}
class LoginLoading extends LoginState {}
class LoginSuccess extends LoginState {}
Exercise Write a LoginBloc and state classes
Define LoginEvent and LoginSubmittedEvent. Write the LoginState abstract class with LoginLoading and LoginSuccess (holds a username) subclasses. LoginBloc should start with LoginLoading and its LoginSubmittedEvent handler should emit LoginSuccess('Ayşe'). In main, trigger the event, wait, and print the username on success.
Show example solution
import 'package:bloc/bloc.dart';
abstract class LoginEvent {}
class LoginSubmittedEvent extends LoginEvent {}
abstract class LoginState {}
class LoginLoading extends LoginState {}
class LoginSuccess extends LoginState {
final String user;
LoginSuccess(this.user);
}
class LoginBloc extends Bloc<LoginEvent, LoginState> {
LoginBloc() : super(LoginLoading()) {
on<LoginSubmittedEvent>((event, emit) =>
emit(LoginSuccess('Ayşe')));
}
}
void main() async {
final bloc = LoginBloc();
bloc.add(LoginSubmittedEvent());
await Future.delayed(Duration(milliseconds: 10));
final state = bloc.state;
if (state is LoginSuccess) {
print(state.user);
}
}
Test yourself
-
How should state classes be designed?
- Immutable, with a separate class per state
- No state class, use a Map instead
- Mutable, with flags inside a single class
- A separate state class for each widget
Show answer
Immutable, with a separate class per state — States should be immutable and each possible state should be modeled with its own class; a single class with flags is error-prone.
-
Define a state class
class LoginSuccess extends ____ {
final String user;
LoginSuccess(this.user);
}
Show answer
class LoginSuccess extends LoginState {
final String user;
LoginSuccess(this.user);
}
-
State parts
- abstract class LoginState
- Base state class
- class LoginLoading extends
- Loading state
- final String user
- State data
- if (state is LoginSuccess)
- State check
Next lesson: BlocListener