Redux & RxJS, будь-які подібності?


113

Я знаю, що Redux є кращою "реалізацією" Flux, а краще кажучи, це перепроектування для спрощення речей (управління станом додатків).

Я багато чув про реактивне програмування (RxJS), але ще не пірнав, щоб це вивчити.

Отже, моє запитання: чи є перетин (що-небудь спільне) між цими двома технологіями чи вони є взаємодоповнюючими? ... або зовсім інше?

Відповіді:


185

Коротше кажучи, це дуже різні бібліотеки для самих різних цілей, але так, є деякі невиразні подібності.

Redux - це інструмент для управління станом у всій програмі. Зазвичай він використовується як архітектура для інтерфейсів користувача. Подумайте про це як про альтернативу (половині) кутових.

RxJS - це реактивна бібліотека програмування. Зазвичай він використовується як інструмент для виконання асинхронних завдань у JavaScript. Подумайте про це як альтернативу Обіцянкам.


Реактивне програмування - парадигма (спосіб роботи та мислення), де зміни даних спостерігаються здалеку . Дані не змінюються на відстані .

Ось приклад зміненого на відстані :

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

Модель змінюється від контролера.

Ось приклад спостережених здалеку :

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

У Журналі ми спостерігаємо зміни даних, які відбуваються в магазині (здалеку), і записуємо на консоль.


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

RxJS також використовує парадигму "Реактивна", але замість того, щоб бути архітектурою, вона дає вам основні будівельні блоки, " Спостережні" , щоб виконати цю схему "спостереження з відстані".

На закінчення, дуже різні речі для різних цілей, але поділіться деякими ідеями.


4
Ні, не слід їх використовувати разом. Люди наслідували Redux за допомогою Rx. Швидкий Google знайде приклади для вас. Якщо ви хочете використовувати Rx для свого реактивного інтерфейсу, перевірте Cycle.js, рамку Andre. Я використовую його останнім часом, і це фантастично. API останнім часом сильно змінюється, але я вважаю, що він нарешті починає заморожувати його частини.
Джоель Дентичі

17
згідно з офіційними документами редукцій , "Вони чудово працюють разом".
galki

12
Вони чудово працюють разом! Існує проміжне програмне забезпечення Redux, яке дає вам можливість використовувати RxJS та Observables для дій Redux. github.com/redux-observable/redux-observable Додатково я написав повідомлення в блозі про те, як: robinwieruch.de/redux-observable-rxjs
Робін Вірух

1
Парадигма Redux допомогла зробити мою базу коду проектів Android більш реактивною. Наші потоки даних, що надходять від кнопок та інших полів для оновлення стану, спільно з RxJava, навантажували нашу читабельність та ефективність. Бібліотеки, безумовно, добре поєднуються, і їх переваги - це мовно-агностичні.
Кенні Worden

Вони чудово працюють разом, але на практиці Reactive може зробити для вас те, що зробив би Redux - синхронізувати стан ваших компонентів для моделювання, тому часто не має сенсу використовувати обидва
Filip Sobczak

32

Вони дуже різні речі.

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

І Redux, як описано в репозиторії github "Redux є передбачуваним контейнером стану для додатків JavaScript".

Redux - це лише інструмент для обробки стану в додатках. Але порівняно, ви можете створити повний додаток лише за RxJS.

Сподіваюся, це допомагає :)


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

4

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

RxJS - це інструментарій для реактивного програмування. Насправді ви можете думати про все, що відбувається у вашому додатку, як потік. RxJS дає дуже багатий набір інструментів для управління цими потоками.

Де перехоплює RxJS і Redux? У надлишку ви оновлюєте свій стан за допомогою дій, і очевидно, що ці дії можна трактувати як потоки. Використовуючи проміжне програмне забезпечення, яке можна спостерігати за редукцією (вам не потрібно), ви можете реагувати так звану "бізнес-логіку" реактивно. Інша справа, що ви можете створити спостереження зі свого магазину скорочення, що іноді може бути простішим, ніж використання покращувача.


2

Коротше кажучи:

Redux: Бібліотека, натхненна Flux, використовується для управління державою .

RxJS: Це ще одна бібліотека Javascript, заснована на філософії реактивного програмування, яка використовується для боротьби з "Потоками" (Спостережні тощо) [Читайте про Реактивне програмування для розуміння концепцій потоку].


1

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

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

Функція чистого реагування буде реалізовуватися лише там, де ви створюєте дані про події, надсилаючи всіх виробників / Суб'єктів.

Якщо у вас є дочірні компоненти, вам потрібно описати, як ці стани поєднуються у ваше. combineLatestможе бути гарною відправною точкою для цього.

Помітні відмінності в реалізації:

  • Без проміжного програмного забезпечення, лише оператори rxjs. Я думаю, що це найбільша сила і слабкість. Ви все ще можете запозичити поняття, але мені важко отримати допомогу таких сестринських спільнот, як redux і cycl.js, оскільки це ще одне користувацьке рішення. Тому мені в цьому тексті потрібно написати «я» замість «ми».

  • Немає перемикача / корпусу чи рядків для типів дій. У вас є більш динамічний спосіб розділення дій.

  • rxjs може використовуватися як інструмент в іншому місці і не міститься в управлінні державою.

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

  • Ви володієте рішенням. Рамки не потрібні. Добре і погане. Ви все одно напишіть власну структуру.

  • Це набагато більше фрактал, і ви можете легко підписатись на зміни з під-дерева або з декількох частин дерева додатків.

    • Здогадайтесь, наскільки легко робити епоси так, як це можна зробити редукційно-обтяжливим? Дійсно легко.

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

Я також замислююся про те, щоб пропустити реагування і піти з примхливою хворобою чи чимось іншим, поки React краще не впорається з реактивними станами. Чому ми повинні будувати нашу державу вгору просто для того, щоб знову її зруйнувати через реквізит? Тому я спробую зробити версію 2 цього зразка з 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, мені вдалося зробити невелику утиліту, яка допомагає створювати редуктори / оновлення. Тож я все ще роблю те саме, але трохи відшліфоване. Найбільша зміна полягає в тому, що я дозволяю кожному вузлу листів підписатися на потік на компонентDidMount і скасувати підписку на компонентDidUnmount. Я також хочу отримати рівень реактивного сервісу, який працює на фронті та резервному просторі. Прогрес там.
Marcus Rådell
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.