Обновление (02.02.2019): более двух лет назад, экспериментируя с RxJS и React, я создал библиотеку, представленную в этом посте. Обратите внимание, что тем временем эта библиотека устарела.

Использование наблюдаемых кажется хорошим делом. Так почему бы нам чаще не использовать его в приложениях React?

С помощью наблюдаемых мы можем легко управлять асинхронными потоками данных, но что такое поток в компоненте React?

Потоки в React

Чтобы определить это, давайте начнем с анализа простого примера ClickCounter:

Это компонент, описывающий асинхронное поведение. Состояние изменяется при каждом click событии в теге button. Или, другими словами, состояние изменяется в результате событий, происходящих с течением времени.

Последовательность текущих событий, упорядоченная во времени, - это определение - потока.

Итак, вместо определения this.state как объекта, который позже будет перезаписан, мы можем определить его более декларативно:

Управление потоками компонентов

Однако, даже при таком определении, как наш компонент узнает, когда нужно обновляться? Кто-то еще должен вызывать this.setState().

Для этого есть несколько существующих решений, но мне это показалось слишком сложным.

Другие, более популярные варианты использования функциональной реактивной парадигмы требуют от вас использования другого фреймворка или другого языка программирования (например, Cycle.js или elm).

Но мне не нравилась идея потерять все хорошее, что предлагает React.

Итак, я создал небольшую библиотеку под названием Recycle, которая является моей попыткой решить эту проблему. Он преобразует описание функционального / реактивного объекта в компонент React.

Вот как выглядит ClickCounter при определении с помощью Recycle:

Работает методом «обезьяны» React.createElement. Перед визуализацией компонента, если запрос выбора соответствует элементу узла, recycle устанавливает встроенный прослушиватель событий, определенный в функции inupdate.

Каждый раз, когда обработчик событий отправляет событие, он вызывает selectedNode.rxSubject.next(e)

Короче говоря, Recycle создает классический компонент React из этого объекта, создавая встроенные обработчики событий и обрабатывая локальное состояние компонента с помощью оператора редуктора «в стиле Redux».

Плюсы

  • Лучшее разделение задач между представлением компонентов и логикой компонентов.

  • Вам не нужны классы, поэтому каждую часть компонента можно определять и тестировать отдельно.
  • Описание компонентов более последовательное. Нет никаких пользовательских handleClick событий или this.setState заявлений, о которых вам нужно беспокоиться.
  • Состояние рассчитывается так же, как и для redux store: state = reducer(state, action).
  • Контейнер Redux выглядит как обычный компонент и более понятно, что он делает.
  • Легко использовать в существующем приложении React (выберите компоненты, которые вы хотите преобразовать).

Минусы

  • Наблюдаемые. Они идут с компромиссами.
  • Вам не нравится идея выбора узлов с помощью имен классов, идентификаторов или тегов.
  • Вам нужно использовать расширенный React API (например, forceUpdateили shouldComponentUpdate)
  • Вам нужен прямой доступ к элементам DOM (с использованием this.refs) для внешних плагинов или аналогичных

Список рассылки

Если подобные сообщения вам интересны, подумайте о подписке на мой список рассылки. Не волнуйтесь, я не буду спамить вас - обычно у меня уходит около двух месяцев на одно сообщение :)