❗❗❗ОБНОВЛЕННАЯ ВЕРСИЯ СТАТЬИ НАХОДИТСЯ ТУТ ❗❗❗
-
Начать писать логику непосредственно в
mapEventToState
,
он у вас быстренько превратится в нечитаемую портянку и придете жаловаться на бойлерплейт.
Если правильно готовить блок, то бойлерплейтом там и не пахнет,
эвенты + стейты + блок умещаются все вместе на 1-2 экранах.
Все запредельно воздушно, даже не надо создавать отдельные файлы под эвенты и стейты.
Все ультра емко получается. -
Мутабельные стейты - нет и еще раз нет, все они должны быть помечены @immutable.
Пэйлоада/нагрузки/данных стейтов это также касается.
Желательно не проморгать и списки также завернуть вUnmodifiableListView
. -
Создавать репозиторий прям сразу в блоке,
а еще хуже доставлять его внутрь через гет_ит или синглтон,
репозиторий может оказаться в блоке только через конструктор, все. -
Попробывать создать "свой блок", ведь "блок, это паттерн, а не пакет".
Конечно, если вы не опытнейший архитектор с кучей ресурсов, временем на тесты/документацию/поддержку.
А также у вас огромное комьюнити контрибьютеров готовое помогать вам в этой задаче.
Эммм... Ну тогда что вы тут делаете? -
У БЛоК'а не должно быть дополнительных публичных методов, геттеров, сеттеров, переменных.
Если у вас не выходит сделать что-то через pub/sub (add/listen), значит вы однозначно делаете это не правильно. -
Не соблюдаете уникальность стейтов:
a) Вместо создания нового объекта стейта вы прокидываете существующий инстанс по ссылке
b) Переносите объект из предидущего стейта в новый по ссылке
c) Забываете про переопределенное равенство у стейта и его пейлоада.
Во всех этих случаях вы рискуете хлопая ресницами удивляться, что заэмиченные стейты не доходят до UI. -
Cubit. Это не стейт менеджер и не архитектура.
На проекте "это" применять нельзя.
Исключение #1 - вы недавно начали знакомиться с реактивщиной и БЛоК'ом,
в таком случае вы можете попробывать начать с него на небольшом демо проекте.
Исключение #2 - у вашего Cubit'а не будет собственных публичных методов, только стандартный listen. Это может быть полезно для ловли сайд эффектов не зависящих напрямую от действий пользователя с интерфейсов. (watch к СУРБД, отслеживание геопозиции, отслеживание состояния интернета). То есть он выступает "прокладкой" между потоком репозитория и интерфейсом. -
Вы забываете про очередность эвентов и
asyncExpand
вtransformEvents
.
Вы должны знать, что по умолчанию все эвенты обрабатываются строго поочередно. -
Вы не используете
Bloc.observer
для перехвата ошибок и логирования.
Или делаетеtry { ... } on dynamic catch (e) { ... }
безrethrow
в своих блоках. -
Начиная с блока (включая) не должно быть импортов флатера.
Исключение, пожалуй, несколько сущностей изflutter/foundation
, которые могут быть заменены сторонними универсальными пакетами, не зависящими от flutter SDK.
Не должно быть виджетов, не должно быть контекста.
- Если я создам БЛоК в initState/didChangeDependencies, добавлю в него эвенты, то они могут быстро обработаться и результирующие стейты не попадут в первый build StreamBuilder/BlocBuilder. Нет. До первого build'а эвенты даже не начнут обрабатываться, не то что эмит стейтов на их основании. А в случае StreamBuilder - первым снэпшотом ВСЕГДА будет то, что вы установите ему в initialData.
- По возможности используйте freezed пакет под эвенты и стейты,
а особенно его фичу с Union и методамиwhen
,maybeWhen
.
Сниппет для Android Studion / IDEA можете посмотреть здесь: https://github.com/dart-side/live-templates/blob/main/bloc.md
Да в том то и дело, что нечего там смотреть, так делать явно не стоит и получается дичайшая лапша с самыми неожиданными ошибками.
Даже нарушение SRP и проблемы с тестированием должны вам прям кричать о том, что вы явно делаете что то не так)
Можете ознакомиться с этим, к примеру: https://habr.com/ru/post/270005/