На некотором расстоянии, наиболее широко используемой библиотекой управления состоянием в React Universe является Redux. У него есть все для этого; отличная документация, активное сообщество, фантастическая основная команда и отличное принятие. Возможно, что более важно, шаблоны проектирования Redux позволяют четко разделить проблемы. Это делает его естественным выбором в более крупных организациях, где способность предсказуемо оценивать и распределять работу важнее краткости или сообразительности.

Моя команда сделала именно это; и хотя мы в основном преуспели и полюбили Redux как фреймворк, мы нашли канонические шаблоны проектирования Redux утомительными даже для команды, готовой повторять код. Позвольте мне прояснить, мы не обижены на Redux (вообще), но было бы полезно обсудить шаблоны и практики. Цель этой статьи - предложить конструктивную критику и изучить возможные варианты.

Что не так с Redux?

  1. Повторяющийся код в нескольких местах. Вы увидите, что названия действий повторяются внутри контейнеров и компонентов, а также в конструкторах действий и редукторах. В типичном приложении слишком много файлов.
  2. Нелокальность бизнес-логики. Мы не увидели никакой пользы от разделения кода управления состоянием на действия и редукторы даже в проектах среднего размера. Возможность видеть объекты в одном окне просмотра повышает продуктивность.
  3. Редукторы. Здесь вы хотите обратимо изменить состояние атома. Есть много способов сделать это, но механизм, который предпочитает Redux, кажется излишне сложным, в то же время расширяя словарный запас, с которым разработчик должен быть знаком, прежде чем стать продуктивным.
  4. Отправлять. Проблема 1, терминология. Проблема 2, механизм соединения Компонентов и Диспетчера через Контейнеры кажется лишним. Способ JavaScriptey использовать модуль или функцию от другого - просто импортировать их.
  5. Асинхронный режим не является встроенным, и в Интернете большинство функций являются асинхронными. Redux нуждается в промежуточном программном обеспечении, таком как redux-thunk, для обработки асинхронных действий. Хотя это популярное значение по умолчанию, redux-thunk не упрощает синхронизацию действий. Выполнение действия после того, как другое завершилось, невозможно с линейным кодом. Как мы покажем позже, эту проблему можно устранить, приняв более простые шаблоны в Redux.

Как решить эту проблему?

Начнем с чистого листа.

Вот три принципа Redux:

  • Единый источник истины
  • Состояние только для чтения
  • Изменения вносятся с использованием чистых функций

Чего еще мы действительно хотим достичь помимо этих прекрасных целей?

Только одно. Мы хотим разделить макет и бизнес-логику.

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

Вот и все. Все остальное - слишком большая работа для слишком маленькой выгоды. Посмотрим, как это можно сделать. Вы можете найти код, используемый в следующем обсуждении, по адресу https://github.com/jeswin/redux/blob/master/examples/redux-lite.

Всего два каталога: Действия и Компоненты.

Действия по импорту компонентов. Нет отправки.

Действия напрямую обновляют Магазин. Не пишите редуктор.

Под капотом это все еще Redux

Под капотом мы все еще используем редуктор. Вызов updateState () создает действие с логическим свойством __replaceState, установленным в значение true. Предопределенный редуктор отслеживает эти действия и заменяет атом текущего состояния новым состоянием.

Все это невидимо для кода приложения. Вам не нужно писать ни одного редуктора.

Вот код для store.js, импортированный выше. Это общий вариант, и его можно переместить в библиотеку.

Асинхронный режим бесплатен

В этой более простой модели нет необходимости в дополнительном промежуточном программном обеспечении для обработки асинхронных действий. Это просто JavaScript.

Вот действие fetchPosts из https://github.com/jeswin/redux/blob/master/examples/redux-lite/src/actions/index.js

Заключение

В коде может быть несколько недостатков, но я вынесу его на обсуждение. Мы еще не начали использовать этот шаблон, так что все это не проверено.

Но дайте ему кружиться.

Изменить: используемые здесь помощники теперь доступны как redux-jetpack.