Найти в Дзене
Petr Tripolsky

Позволяет ли Redux писать функционально чистый код?

Когда-то давно, мне повезло работать на проекте, где все обращения к backend были обернуты в action-creators с использованием библиотеки redux-thunk. Эта библиотека имеет культовое значение для экосистемы Redux, так как позволяет писать обращения к backend без применение генераторов, в отличие от redux-saga В рамках NDA я не могу назвать организацию и опубликовать оригинал. Но я могу написать псевдокод. Как видно, в результате исполнения getRepos, из-за закомментированного ключевого слова await, в целевой reducer состояния улетит пустой массив repos. На боевом проекте же его просто забыли написать :-) Начинающий разработчик всё-таки смог получить список репозиториев по ссылке, но сделал это с применением forceUpdate(). Это создало плавающий баг, который не воспроизводился на тестовом контуре при финальном интеграционном тестировании Проблема После инцидента, у меня возникла навящивая идея о том, что Redux не обеспечивает функциональную чистоту состояния приложения. Так же интересно был
Оглавление

Когда-то давно, мне повезло работать на проекте, где все обращения к backend были обернуты в action-creators с использованием библиотеки redux-thunk. Эта библиотека имеет культовое значение для экосистемы Redux, так как позволяет писать обращения к backend без применение генераторов, в отличие от redux-saga

В рамках NDA я не могу назвать организацию и опубликовать оригинал. Но я могу написать псевдокод. Как видно, в результате исполнения getRepos, из-за закомментированного ключевого слова await, в целевой reducer состояния улетит пустой массив repos. На боевом проекте же его просто забыли написать :-)

-2

Начинающий разработчик всё-таки смог получить список репозиториев по ссылке, но сделал это с применением forceUpdate(). Это создало плавающий баг, который не воспроизводился на тестовом контуре при финальном интеграционном тестировании

Проблема

После инцидента, у меня возникла навящивая идея о том, что Redux не обеспечивает функциональную чистоту состояния приложения. Так же интересно было разобрать таблицу возможных значений данной функции. Расмотрим пример эквивалентный по сути предидущему

Является ли эта функция pure функцией?

-3

На первый взгляд, да, однако…

-4

Верным вариантом написания pure функции будет функция с определенными входными параметрами

-5

Это работает при использовании простых типов данных. Но при попытке определения сложного типа данных интерфейсом нет гарантии функциональной простоты внутренней реализации, так как интерфейс осуществляет проверку времени компиляции.

-6

Рассмотрим исходный код примера применения селекторов в redux-form, страница Selecting Form Values Example.

-7

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

Функция mapStateToProps при подобном использовании имеет бесконечный список возвращаемых значений, он расширяется при последующих итерациях разработки вместе с правками ui, осуществляющим определение свойств компонента.

Решение

Коллеги! Пишите свои шаблонизаторы. Возможно, я покажусь старомодным, но применение JSON шаблонов для генерации формы позволит убрать копипасту и решить следующие проблемы

Автоматизировать создание внутреннего состояния формы и сохранение изменений

Огромное колличество кода приложения приходится на копипасту Create-Read-Update-Delete. Если нужно восстановить ввод при повторном открытии страницы без сохранения, вы не обойдетесь без шаблонизатора

Принцип единой ответственности

Свойство canSubscribeByEmail внутри селектора выше не привязано к полю и в любой момент при повторном использовании другим программистом произойдет коллизия. JSON шаблон позволяет разнести коллбеки isDisabled, isInvalid, isVisible непосредственно к полям, что обеспечит единую ответственность

Можно упростить адаптивную верстку

Ограничив варианты компоновки ограниченным множеством полей ввода и адаптивной сеткой на phoneColomns, tabletColumns, desktopColumns, легко обеспечить применение фирменного стиля по всему приложению, так как большую роль играет разница компонентов из разных источников и отступы

Наличие шаблонизатора критично для списочных форм

Если для backend существует единый стандарт json:api, например, nest-paginate, то для frontend я часто натыкался на копипасту состояний фильтров, сортировок и верстки списочной формы через <List> и <ListItem>. Это неправильно.

Пример использования шаблонизатора в коде

Предположим, есть карточка списка элементов с адаптивным отображением

-8

Она может уместиться в 125 строчек кода! А теперь представьте, сколько времени у вас займет написание этой формы вручную

-9

Вынесите в JSON шаблоны хоть что-то!

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

-10

Спасибо за внимание)