Заметки об effector (непутевые)
189 subscribers
14 links
Периодические заметки о том как варить суп, чтобы обои не отклеивались
Download Telegram
1. Введение

В виду повторяющихся вопросов, недопониманий в чате и карантина, когда всем впадлу смотреть видосы с онлайн-трансляций (и я понимаю почему) решил объединить то, о чем я повествую в текстовом виде и поставить жирную точку в введении в эффектор

Зачем вообще это нужно? Потому что это инструмент, который в действительности может помочь облегчить рутину фронтэндеров. Ведь можно будет забыть почти полностью о пропсах, об их типизации, о кусках логики внутри компонентов, заучивании десятка другого операторов, использовать прокси или декораторы и при этом получать самый мощный инструмент по организации датафлоу на рынке, предоставляющий лишь функции и объекты.
Единственная проблема получить доступное введение в технологию так как нужно несколько перестроить майндсет. Я полагаю, что нашел путь к более мягкому "въезду", поэтому собираю ультимативную инструкцию в этой серии постов.
Заметки об effector (непутевые)
1. Введение В виду повторяющихся вопросов, недопониманий в чате и карантина, когда всем впадлу смотреть видосы с онлайн-трансляций (и я понимаю почему) решил объединить то, о чем я повествую в текстовом виде и поставить жирную точку в введении в эффектор…
2. Приложение это система

Да, это действительно важная деталь в понимании и зачем вообще вот это все.
Давайте по шагам попробуем дойти до этого тезиса:
1) Цельные ли приложения по своей природе?Да
2) Могут ли приложения быть поделены по определенному признаку? Да
3) По какому? Зоны ответственности
4) Соединены ли зоны ответственности между собой? Да, определенно, так как это части конкретного приложения. Более того, они взаимодействуют друг с другом
5) А что такое система? Множество связанных вещей(зон ответственности), которые взаимодействуют друг с другом

Вау! Всего-навсего 5 шагов и подвели к такому тезису. Брависсимо!
Заметки об effector (непутевые)
2. Приложение это система Да, это действительно важная деталь в понимании и зачем вообще вот это все. Давайте по шагам попробуем дойти до этого тезиса: 1) Цельные ли приложения по своей природе?Да 2) Могут ли приложения быть поделены по определенному признаку?…
3. Возвращаемся к нашим баранам (эффекторам)

Я специально в первом посте выделил слово датафлоу. Так как оно ключевое, а не вот это закрепившееся сокращем стм. Это ведет к заблуждениям. Стейт это лишь элемент для построения бизнес-логики. А не всеобъемлющее целое.

Кстати, об элементах. Эффектор предоставляет четыре юнита, оперируя которыми вы сможете построить бизнес-логику любой сложности: вода, земля, огонь и воздух
Заметки об effector (непутевые)
3. Возвращаемся к нашим баранам (эффекторам) Я специально в первом посте выделил слово датафлоу. Так как оно ключевое, а не вот это закрепившееся сокращем стм. Это ведет к заблуждениям. Стейт это лишь элемент для построения бизнес-логики. А не всеобъемлющее…
4. Юниты: Event

Первый и самый важный. Дело в том, что мы как фронтэндеры живем в событийно-ориентированном окружении (DOM ака верстка). При построении бизнес-логики веб-приложений(те которые рядом с DOMом) глупо было бы ориентироваться на иную модель. Даже при разговоре c бизнесом в лице менеджеров и выше нередко можно услышать фразы наподобие: "Пользователь заходит, и тут наша фича такая ХОБА". Неявным образом в данном разговоре подразумеваются события:
1) пользователь заходит
2) фича делает хоба

Определение события со словарика.
Заметки об effector (непутевые)
4. Юниты: Event Первый и самый важный. Дело в том, что мы как фронтэндеры живем в событийно-ориентированном окружении (DOM ака верстка). При построении бизнес-логики веб-приложений(те которые рядом с DOMом) глупо было бы ориентироваться на иную модель. Даже…
5. Юниты: Store

Ух, вот она жемчужина СТМ. Сторчик, Стореныш.

Объект для хранения значений. Необходимо задавать дефолтное значение(можно все кроме undefined). При прилете повторяющегося(эквивалентного предыдущему) значения не тригернет апдейт.

Обработчик для прилетевших событий представляет собой редьюсер (не мутируем текущий стейт), в случае возврата undefined в обработчике апдейт не тригернется

Учитывая предыдущий апроач с зонами ответственности, можно вывести следующую рекомендацию: никаких сингл сторов на все приложение. Я серьезно. Зоны ответственности позволяют нам иметь как минимум один стор под своим патронажем. И нет, не поля одного большого объекта. Независимые легкие сторы для каждой зоны ответственности.

Комбинировать их в гигастор не составит труда при возникшей необходимости.
Заметки об effector (непутевые)
5. Юниты: Store Ух, вот она жемчужина СТМ. Сторчик, Стореныш. Объект для хранения значений. Необходимо задавать дефолтное значение(можно все кроме undefined). При прилете повторяющегося(эквивалентного предыдущему) значения не тригернет апдейт. Обработчик…
6: Юниты: Effect

Ключевой для понимания юнит.
Технически признаками эффекта являются (хотя бы один):
-влияние на окружение вне системы (запросы на сервер, локалсторадж)
- подверженность влиянию окружения (process.env)

Но, концептуально, если событие это штука, которая происходит всегда, то эффект же предоставляет конструкцию, которая позволит обрабатывать исключения(то есть отсутствие гарантии, что все действо внутри обработчика будет завершено с успехом)

Когда мы можем ловить исключения?
-запросы
-работы с локал сторадж
-работа с third-party API
-произвольный участок кода, где разработчику жуть как хочется написать явный throw

Эффект предоставляет нам handler, в который будут складироваться все подобные сомнительные конструкции.

Таким образом, "прожевывая" сомнительные конструкции, эффект эмитит события об успехе(.done) или о несварении (.fail). Во время работы так же доступно булево поле-стор .pending, которое явно скажет о том в процессе эффект или нет.

Для тех кому все равно на исход любезно предоставлено событие .finally, которое эмитится всегда.
Заметки об effector (непутевые)
7. Стандартные юниты Все вышеобозначенные три юнита являются стандартными. Это важное уточнение так как дальше этот термин будет использоваться для краткости.
8. Юниты: Domain

Домен это неймспейс для всех стандартных юнитов. Предоставляет хуки на создание стандартных юнитов, находящихся под патронажем этого домена. Что полезно для массовых операций. Домен может быть свободно создан внутри домена. Все юниты внутри домена могут выведены через domain.history

P.S. домены необходимы при SSR, а также при написании тестов, покрывающих большинство сценариев нашей системы
Заметки об effector (непутевые)
7. Стандартные юниты Все вышеобозначенные три юнита являются стандартными. Это важное уточнение так как дальше этот термин будет использоваться для краткости.
9. Подготовка данных

Подобно караванам с товарами ивенты распространяют данные по нашей системе(только грабить их не нужно). Периодически нам нужно эти данные подготовить: добавить в эти данные какое-нибудь статическое значение или умножить пришедшую в данных цифру на два.
Для таких задач служат три вещи:
1) пожалуй самой «плоской» версией для подготовки данных между юнитом «отправки» и юнитом «назначения» (датафлоу все-таки) является поле fn в операторе sample. Но к нему вернусь через пару глав, так как обо всем по порядку.
2) остальные варианты являются методами события непосредственно. Первый из них event.map позволяет трансформировать payload, пришедший в событие как вам заблагорассудится лишь с одним ограничением: функция-трансформер должна быть чистой (то есть не содержать сайд-эффектов). Данный метод события вернет новое событие, которое будет неразрывно связано с оригинальным незамедлительным вызовом, как только оригинальное было «тригернуто».
3) и последний вариант это event.prepend . Если с .map мы взаимодействуем как с постобработчиком, то .prepend, напротив, будет являться прелюдией к оригинальному событию. Соответственно, возвращать будет событие которое исполнит функцию-трансформер и затем незамедлительно вызовет оригинальное событие. Какое можно найти этому применение?
Например, эффект по получению баланса определенной валюты. Обработчик для всех валют одинаковый, отличие будет будет лишь в статическом коде валюты. Таким образом, можно создать множество «препенднутых» событий, функция-трансформер которого примиксовывает в аргумента вызова статический код валюты и решить поставленную задачу.
Заметки об effector (непутевые)
5. Юниты: Store Ух, вот она жемчужина СТМ. Сторчик, Стореныш. Объект для хранения значений. Необходимо задавать дефолтное значение(можно все кроме undefined). При прилете повторяющегося(эквивалентного предыдущему) значения не тригернет апдейт. Обработчик…
10. Подготовка данных стора в необходимой форме

Данные из сторов тоже не последние люди в нашем цирке под названием датафлоу, поэтому как-то несправедливо было бы обделить стор методом для подготовки данных. Стор подобно событию имеет метод .map, в котором можно трасформировать стор по заранее указанным правилам. Такой стор называется вычисляемым стором. Вычисляться он будет только при апдейте оригинального. Не больше и не меньше.
Применение? Например, стор вам нужен в форме ассоциативного массива(ключ-значение) и в форме обычного массива объектов.
11. Датафлоу. Начало

Мы успели затронуть как обрабатывать данные в рамках одного стандартного юнита. А как же быть когда их несколько??
Вот тут-то и начинается самое интересное - декларативная связь юнитов! Первым самым простым оператором является оператор forward. Его апи достаточно явное: поля from и to, принимающие любой стандартный юнит. Его исполнение означает, что поле to явно подписано на триггер(изменение значения в сторе или вызов события) поля from и будет тригернуто соответственно после.

P. S. Только не надо подписывать завершение эффекта на его вызов - в вас ударит молния.