Sobes.tech
Назад к вопросам
Middle
209
questionbank

Существуют ли примеры использования BLoC и Cubit в вашем проекте?

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

Ожидают услышать, что есть практический опыт с BLoC/Cubit и понимание, где какой подход лучше применять. Важно показать, что выбор делается осознанно: для сложной бизнес-логики — BLoC, для более простого локального состояния — Cubit. Хорошо, если есть пример из реального проекта: авторизация, фильтры, форма, пагинация, корзина.

Определение:

BLoC и Cubit — это подходы к управлению состоянием во Flutter через отдельный слой логики, который отделяет UI от бизнес-логики.
Cubit проще: он хранит состояние и меняет его методами напрямую.
BLoC более формальный: состояние меняется в ответ на события, что удобно для сложных сценариев и явного потока данных.

Пример использования:

В проекте BLoC удобно использовать для экрана списка товаров с фильтрами, пагинацией и загрузкой данных с сервера. Cubit подходит для формы входа, переключателя темы, локального фильтра или счетчика избранного.

// Cubit для простой формы логина
class LoginCubit extends Cubit<LoginState> {
  LoginCubit() : super(const LoginState.initial());

  Future<void> login(String email, String password) async {
    emit(const LoginState.loading());

    try {
      await authRepository.login(email: email, password: password);
      emit(const LoginState.success());
    } catch (e) {
      emit(LoginState.error(e.toString()));
    }
  }
}
// BLoC для списка товаров с событиями
abstract class ProductsEvent {}

class LoadProducts extends ProductsEvent {}
class LoadMoreProducts extends ProductsEvent {}
class ApplyFilter extends ProductsEvent {
  final String category;
  ApplyFilter(this.category);
}

class ProductsBloc extends Bloc<ProductsEvent, ProductsState> {
  ProductsBloc() : super(const ProductsState.initial()) {
    on<LoadProducts>((event, emit) async {
      emit(const ProductsState.loading());
      final products = await repository.fetchProducts();
      emit(ProductsState.loaded(products));
    });

    on<ApplyFilter>((event, emit) async {
      final filtered = await repository.fetchProducts(category: event.category);
      emit(ProductsState.loaded(filtered));
    });
  }
}

Пояснение кода:

В примере с Cubit есть метод login, который последовательно переводит состояние из initial в loading, а затем в success или error. Это удобно, когда действие одно и логика не требует отдельной модели событий.

В примере с BLoC сначала описываются события: загрузка, подгрузка, применение фильтра. Затем в классе через on<...> задается реакция на каждое событие. Такой подход делает поток изменений состояния более явным и удобным для расширения.

По шагам это выглядит так:

  1. UI вызывает метод Cubit или отправляет событие в BLoC.
  2. Логика выполняет асинхронную операцию через репозиторий.
  3. В зависимости от результата эмитится новое состояние.
  4. UI подписан на состояние и перестраивается автоматически.

Ключевые моменты:

  • Cubit — проще и короче, подходит для локального или несложного состояния.
  • BLoC — лучше, когда есть много событий, переходов и бизнес-логики.
  • В обоих случаях UI должен быть максимально “тонким” и не содержать бизнес-логику.
  • Состояния лучше делать явными: loading, success, error, empty.
  • Хорошая практика — выносить доступ к данным в repository, а не держать его в UI.
  • На собеседовании важно показать не только знание API, но и умение выбрать подход под задачу.