Redux и RxJS, есть ли сходства?


113

Я знаю, что Redux - лучшая «реализация» Flux, или, точнее говоря, это редизайн для упрощения вещей (управление состоянием приложения).

Я много слышал о реактивном программировании (RxJS), но еще не погрузился в его изучение.

Итак, мой вопрос: есть ли пересечение (что-то общее) между этими двумя технологиями или они дополняют друг друга? ... или совсем другое?

Ответы:


185

Короче говоря, это очень разные библиотеки для самых разных целей, но да, есть некоторые смутные сходства.

Redux - это инструмент для управления состоянием всего приложения. Обычно он используется в качестве архитектуры для пользовательского интерфейса. Думайте об этом как об альтернативе (половине) Angular.

RxJS - это библиотека реактивного программирования. Обычно он используется как инструмент для выполнения асинхронных задач в JavaScript. Считайте это альтернативой обещаниям.


Реактивное программирование - это парадигма (способ работы и мышления), в которой изменения данных наблюдаются на расстоянии . Данные не меняются на расстоянии .

Вот пример изменения на расстоянии :

// In the controller.js file
model.set('name', 'George');

Модель изменяется от контроллера.

Вот пример наблюдения с расстояния :

// logger.js
store.subscribe(function (data) {
    console.log(data);
});

В Регистраторе мы наблюдаем за изменениями данных, которые происходят в Store (на расстоянии), и записываем в консоль.


Redux немного использует реактивную парадигму: Магазин является реактивным. Вы не устанавливаете его содержание на расстоянии. Вот почему store.set()в Redux нет. Магазин наблюдает за действиями на расстоянии и изменяется сам. А Магазин позволяет другим наблюдать за своими данными на расстоянии.

RxJS также использует парадигму Reactive, но вместо того, чтобы быть архитектурой, он дает вам базовые строительные блоки, Observables , для выполнения этого шаблона «наблюдения с расстояния».

В заключение, очень разные вещи для разных целей, но поделитесь некоторыми идеями.


4
Нет, не используйте их вместе. Люди эмулировали Redux с помощью Rx. Быстрый Google найдет для вас примеры. Если вы хотите использовать Rx для своего реактивного пользовательского интерфейса, проверьте Cycle.js, фреймворк Андре. Я использую его в последнее время, и это потрясающе. API в последнее время сильно изменился, но я считаю, что он наконец-то начинает его замораживать.
Joel Dentici

17
согласно официальным документам redux , «они отлично работают вместе».
galki

12
Они отлично работают вместе! Существует промежуточное ПО Redux, которое дает вам возможность использовать RxJS и Observables для действий Redux. github.com/redux-observable/redux-observable Кроме того, я написал в блоге сообщение о том, как это сделать: robinwieruch.de/redux-observable-rxjs
Робин Веруч

1
Парадигма Redux помогла сделать мою базу кода проекта Android более реактивной. Наши потоки данных, поступающие от кнопок и других полей для обновления состояния, в сочетании с RxJava, повысили нашу читаемость и производительность. Библиотеки определенно хорошо сочетаются друг с другом, и их преимущества не зависят от языка.
Kenny Worden

Они отлично работают вместе, но на практике Reactive может сделать для вас то же, что и Redux - синхронизировать состояние ваших компонентов с моделью, поэтому часто нет смысла использовать оба
Филип Собчак

32

Это очень разные вещи.

RxJS может использоваться для реактивного программирования и представляет собой очень полную библиотеку с более чем 250 операторами.

И Redux, как описано в репозитории github, «Redux - это контейнер с предсказуемым состоянием для приложений JavaScript».

Redux - это просто инструмент для обработки состояния в приложениях. Но для сравнения вы можете создать полноценное приложение только на RxJS.

Надеюсь это поможет :)


3
Ваш ответ тоже хорош @cmdv. Я не видел этого, когда писал свой.
Андре Стальц

4

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

RxJS - это набор инструментов для реактивного программирования. Фактически вы можете думать обо всем, что происходит в вашем приложении, как о потоке. RxJS предоставляет очень богатый набор инструментов для управления этими потоками.

Где перехватывает RxJS и Redux? В redux вы обновляете свое состояние с помощью действий, и, очевидно, эти действия можно рассматривать как потоки. Используя промежуточное программное обеспечение, такое как redux-observable (вам не обязательно), вы можете реализовать свою так называемую «бизнес-логику» реактивным способом. Другое дело, что вы можете создать наблюдаемое из своего хранилища redux, что иногда может быть проще, чем использование усилителя.


2

Короче говоря:

Redux: библиотека, вдохновленная Flux, используемая для управления состоянием .

RxJS: это еще одна библиотека Javascript, основанная на философии реактивного программирования, используемая для работы с «потоками» (наблюдаемые объекты и т. Д.) [Прочтите о реактивном программировании, чтобы понять концепции потоков].


1

Я просто хотел добавить некоторые прагматические отличия от того, когда я делал RxJS-код, вдохновленный Redux.

Я сопоставил каждый тип действия с экземпляром Subject. Каждый компонент с отслеживанием состояния будет иметь субъект, который затем отображается в функцию-редуктор. Все потоки редуктора объединяются mergeи затем scanвыводят состояние. Значение по умолчанию устанавливается startWithнепосредственно перед scan. Я использовал publishReplay(1)для состояний, но могу удалить его позже.

Функция react pure render будет только в том месте, где вы производите данные события, отправляя всех производителей / субъектов.

Если у вас есть дочерние компоненты, вам нужно описать, как эти состояния объединяются в ваше. combineLatestможет быть хорошей отправной точкой для этого.

Заметные отличия в реализации:

  • Никакого промежуточного ПО, только операторы rxjs. Я считаю, что это самая большая сила и слабость. Вы все еще можете позаимствовать концепции, но мне трудно получить помощь от родственных сообществ, таких как redux и cycle.js, поскольку это еще одно нестандартное решение. Поэтому в этом тексте мне нужно писать «я» вместо «мы».

  • Нет переключателя / регистра или строк для типов действий. У вас есть более динамичный способ разделения действий.

  • rxjs можно использовать как инструмент в другом месте и не входит в управление состоянием.

  • Меньшее количество производителей, чем типов действий (?). Я не уверен в этом, но у вас может быть много реакций в родительских компонентах, которые слушают дочерние компоненты. Это означает меньше императивного кода и меньшую сложность.

  • Решение принадлежит вам. Никаких рамок не требуется. Хорошо и плохо. В любом случае вы в конечном итоге напишете свой собственный фреймворк.

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

    • Угадайте, насколько легко делать эпосы, как это делают redux-obseravble? Действительно просто.

Я также работаю над гораздо большими преимуществами, когда дочерние компоненты описываются как потоки. Это означает, что нам не нужно собирать родительское и дочернее состояние в редукторах, поскольку мы можем просто («просто») рекурсивно комбинировать состояния на основе структуры компонентов.

Я также думаю о том, чтобы пропустить реакцию и пойти на снаббдом или что-то еще, пока React не будет лучше справляться с реактивными состояниями. Почему мы должны строить свое состояние вверх только для того, чтобы снова разбить его через свойства? Итак, я попробую создать вторую версию этого шаблона с помощью Snabbdom.

Вот более продвинутый, но небольшой фрагмент, в котором файл state.ts создает поток состояний. Это состояние компонента ajax-формы, которое получает объект полей (входов) с правилами проверки и стилями css. В этом файле мы просто используем имена полей (ключи объектов) для объединения всех дочерних состояний в состояние формы.

export default function create({
  Observable,
  ajaxInputs
}) {
  const fieldStreams = Object.keys(ajaxInputs)
  .map(function onMap(fieldName) {
    return ajaxInputs[fieldName].state.stream
    .map(function onMap(stateData) {
      return {stateData, fieldName}
    })
  })

  const stateStream = Observable.combineLatest(...fieldStreams)
  .map(function onMap(fieldStreamDataArray) {
    return fieldStreamDataArray.reduce(function onReduce(acc, fieldStreamData) {
    acc[fieldStreamData.fieldName] = fieldStreamData.stateData
    return acc
  }, {})
  })

  return {
    stream: stateStream
  }
}

Хотя код может мало что сказать по отдельности, он показывает, как вы можете построить состояние вверх и как вы можете легко создавать динамические события. Цена, которую придется заплатить, состоит в том, что вам нужно понимать другой стиль кода. И я люблю платить эту цену.


Год спустя, я нашел ваш ответ и думаю, что он все еще актуален! Я сделал нечто подобное и согласен со всеми вашими пунктами. Но все же вопрос: вы все еще думаете так же сегодня или с тех пор ушли?
Xceno

1
Мне нужно пересмотреть критику типов переключателей / случаев и действий в Redux. Я все еще пишу код таким же образом, но пытаюсь понять, как заставить его работать на стороне сервера. Когда дело доходит до кода React, мне удалось сделать небольшую утилиту, которая помогает создавать редюсеры / программы обновления. Так что я все еще делаю то же самое, но немного более отточенным. Самым большим изменением является то, что я позволил каждому конечному узлу подписаться на поток на componentDidMount и отказаться от подписки на componentDidUnmount. Я также хочу получить уровень реактивного сервиса, который работает как во фронтенде, так и в бэкэнде. Делаем там прогресс.
Маркус Роделл
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.