В чем суть BLoC во Flutter
Что проверяют
Понимаете ли вы, зачем отделять бизнес-логику от виджетов и как BLoC это делает через события и состояния. Следом обычно спрашивают, чем Bloc отличается от Cubit и как вы его тестируете.
Как отвечать
BLoC (Business Logic Component) это паттерн, в котором виджет не меняет состояние сам, а отправляет событие. Компонент логики обрабатывает его и выдаёт новое состояние, виджет перерисовывается по нему. Под капотом состояния отдаются как Stream, а на практике имеют в виду пакет flutter_bloc. Из веба ближайшая аналогия это Redux: событие похоже на action, обработчик на reducer.
- события: что произошло, например
LoginSubmittedилиItemsRefreshed; - состояния: неизменяемые классы вида «загрузка, данные, ошибка», часто на
sealed classи с равенством черезEquatableилиfreezed; Bloc: обработчики регистрируются в конструкторе черезon<Event>((event, emit) async {...}). СтарыйmapEventToStateудалён в bloc 8, код с ним из старых статей не соберётся;Cubit: упрощённый вариант без событий, методы сразу вызываютemit. Подходит, когда не нужны трансформации потока событий;- виджеты:
BlocProviderвнедряет экземпляр в дерево,BlocBuilderперестраивает UI,BlocListenerделает побочные эффекты вроде навигации и снекбаров,BlocSelectorподписывается на часть состояния.
Два момента показывают реальный опыт. Первый: состояние, равное текущему, повторно не эмитится, поэтому без правильного == UI либо не обновится, либо будет перерисовываться лишний раз. Второй: события по умолчанию обрабатываются параллельно, а для поиска по мере ввода нужен transformer: restartable() из bloc_concurrency, чтобы старый запрос отменялся.
Тестируют через bloc_test: blocTest задаёт событие и ожидаемую последовательность состояний, репозиторий подменяется моком.
Где спотыкаются
Тащат в BLoC BuildContext и навигацию. Логика должна жить без Flutter, иначе её не проверить чистым Dart-тестом.
Мутируют список внутри состояния и вызывают emit(state). Объект тот же, равенство совпало, изменение никто не увидит.
Делают один гигантский BLoC на всё приложение вместо отдельного на фичу или экран.