Skip to content

Instantly share code, notes, and snippets.

@PlugFox
Last active February 13, 2024 12:26
Show Gist options
  • Save PlugFox/7ee89778d0145f3bba704dbc4e4002da to your computer and use it in GitHub Desktop.
Save PlugFox/7ee89778d0145f3bba704dbc4e4002da to your computer and use it in GitHub Desktop.
БИНГО ошибок при создании BLoC'а

БИНГО ошибок при создании BLoC'а

❗❗❗ОБНОВЛЕННАЯ ВЕРСИЯ СТАТЬИ НАХОДИТСЯ ТУТ ❗❗❗

ОШИБКИ:

  1. Начать писать логику непосредственно в mapEventToState,
    он у вас быстренько превратится в нечитаемую портянку и придете жаловаться на бойлерплейт.
    Если правильно готовить блок, то бойлерплейтом там и не пахнет,
    эвенты + стейты + блок умещаются все вместе на 1-2 экранах.
    Все запредельно воздушно, даже не надо создавать отдельные файлы под эвенты и стейты.
    Все ультра емко получается.

  2. Мутабельные стейты - нет и еще раз нет, все они должны быть помечены @immutable.
    Пэйлоада/нагрузки/данных стейтов это также касается.
    Желательно не проморгать и списки также завернуть в UnmodifiableListView.

  3. Создавать репозиторий прям сразу в блоке,
    а еще хуже доставлять его внутрь через гет_ит или синглтон,
    репозиторий может оказаться в блоке только через конструктор, все.

  4. Попробывать создать "свой блок", ведь "блок, это паттерн, а не пакет".
    Конечно, если вы не опытнейший архитектор с кучей ресурсов, временем на тесты/документацию/поддержку.
    А также у вас огромное комьюнити контрибьютеров готовое помогать вам в этой задаче.
    Эммм... Ну тогда что вы тут делаете?

  5. У БЛоК'а не должно быть дополнительных публичных методов, геттеров, сеттеров, переменных.
    Если у вас не выходит сделать что-то через pub/sub (add/listen), значит вы однозначно делаете это не правильно.

  6. Не соблюдаете уникальность стейтов:
    a) Вместо создания нового объекта стейта вы прокидываете существующий инстанс по ссылке
    b) Переносите объект из предидущего стейта в новый по ссылке
    c) Забываете про переопределенное равенство у стейта и его пейлоада.
    Во всех этих случаях вы рискуете хлопая ресницами удивляться, что заэмиченные стейты не доходят до UI.

  7. Cubit. Это не стейт менеджер и не архитектура.
    На проекте "это" применять нельзя.
    Исключение #1 - вы недавно начали знакомиться с реактивщиной и БЛоК'ом,
    в таком случае вы можете попробывать начать с него на небольшом демо проекте.
    Исключение #2 - у вашего Cubit'а не будет собственных публичных методов, только стандартный listen. Это может быть полезно для ловли сайд эффектов не зависящих напрямую от действий пользователя с интерфейсов. (watch к СУРБД, отслеживание геопозиции, отслеживание состояния интернета). То есть он выступает "прокладкой" между потоком репозитория и интерфейсом.

  8. Вы забываете про очередность эвентов и asyncExpand в transformEvents.
    Вы должны знать, что по умолчанию все эвенты обрабатываются строго поочередно.

  9. Вы не используете Bloc.observer для перехвата ошибок и логирования.
    Или делаете try { ... } on dynamic catch (e) { ... } без rethrow в своих блоках.

  10. Начиная с блока (включая) не должно быть импортов флатера.
    Исключение, пожалуй, несколько сущностей из flutter/foundation, которые могут быть заменены сторонними универсальными пакетами, не зависящими от flutter SDK.
    Не должно быть виджетов, не должно быть контекста.

ЗАБЛУЖДЕНИЯ:

  1. Если я создам БЛоК в initState/didChangeDependencies, добавлю в него эвенты, то они могут быстро обработаться и результирующие стейты не попадут в первый build StreamBuilder/BlocBuilder. Нет. До первого build'а эвенты даже не начнут обрабатываться, не то что эмит стейтов на их основании. А в случае StreamBuilder - первым снэпшотом ВСЕГДА будет то, что вы установите ему в initialData.

СОВЕТЫ:

  1. По возможности используйте freezed пакет под эвенты и стейты,
    а особенно его фичу с Union и методами when, maybeWhen.
    Сниппет для Android Studion / IDEA можете посмотреть здесь: https://github.com/dart-side/live-templates/blob/main/bloc.md
@PlugFox
Copy link
Author

PlugFox commented Oct 22, 2021

@August79

_ у вашего Cubit'а не будет собственных публичных методов, только стандартный listen. _

почему?

Потому что в противном случае это нисколько не будет отличаться от того, что в флатере называют "simple state managment" через ChangeNotifier. У вас не будет очередности событий и как следствие поимете странные race condition когда за состоянием "разлогиниваемся" может запросто идти состояние "залогинен".

Ну и также этот подход ничуть не будет отличаться от "вызывать методы репозитория сразу из слоя виджетов", чем, собственно и будет являться.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment