Налаштування архітектури BLoC для Flutter-додатків
BLoC (Business Logic Component) — офіційно рекомендований паттерн управління станом від команди Flutter. Заснований на потоках подій та станів: UI відправляє Event, BLoC обробляє й видає State. Бібліотека flutter_bloc від Felix Angelov стала стандартом у великих Flutter-проектах.
Як BLoC працює на практиці
// Events
abstract class ProfileEvent {}
class ProfileLoaded extends ProfileEvent {
final String userId;
ProfileLoaded(this.userId);
}
class ProfileRefreshed extends ProfileEvent {}
// States
abstract class ProfileState {}
class ProfileInitial extends ProfileState {}
class ProfileLoading extends ProfileState {}
class ProfileSuccess extends ProfileState {
final UserProfile profile;
ProfileSuccess(this.profile);
}
class ProfileFailure extends ProfileState {
final String error;
ProfileFailure(this.error);
}
// BLoC
class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
final UserRepository _repository;
ProfileBloc(this._repository) : super(ProfileInitial()) {
on<ProfileLoaded>(_onLoaded);
on<ProfileRefreshed>(_onRefreshed);
}
Future<void> _onLoaded(ProfileLoaded event, Emitter<ProfileState> emit) async {
emit(ProfileLoading());
try {
final profile = await _repository.getProfile(event.userId);
emit(ProfileSuccess(profile));
} catch (e) {
emit(ProfileFailure(e.toString()));
}
}
}
У віджеті:
BlocBuilder<ProfileBloc, ProfileState>(
builder: (context, state) {
return switch (state) {
ProfileLoading() => const CircularProgressIndicator(),
ProfileSuccess(:final profile) => ProfileView(profile: profile),
ProfileFailure(:final error) => ErrorView(error: error),
_ => const SizedBox(),
};
},
)
BLoC vs Cubit
Cubit — спрощена версія BLoC без Events. Методи Cubit викликаються напрямо: profileCubit.load(userId). Підходить для простих екранів. BLoC з Events дає журнал подій та краще тестується при складній логіці з кількома джерелами подій.
Що налаштовуємо
Структура проекту: lib/features/profile/bloc/, data/, domain/. Підключення flutter_bloc, equatable (для правильного порівняння станів). Реєстрація BLoC-ів через MultiBlocProvider у корені додатку або через BlocProvider на рівні роуту. Налаштування BlocObserver для глобального логування подій та помилок.
Тестування через bloc_test:
blocTest<ProfileBloc, ProfileState>(
'emits [Loading, Success] when ProfileLoaded is added',
build: () => ProfileBloc(mockRepository),
act: (bloc) => bloc.add(ProfileLoaded('user-123')),
expect: () => [ProfileLoading(), ProfileSuccess(tProfile)],
);
Терміни
Налаштування BLoC-архітектури з нуля: 2–3 дні. Рефакторинг setState-проекту: 1–2 тижні. Вартість — після аналізу.







