Redux & RxJS, des similitudes?

113

Je sais que Redux est une meilleure "implémentation" de Flux, ou mieux dire que c'est une refonte pour simplifier les choses (gestion de l'état des applications).

J'ai beaucoup entendu parler de la programmation réactive (RxJS), mais je n'ai pas encore plongé pour l'apprendre.

Ma question est donc la suivante: y a-t-il une intersection (quelque chose en commun) entre ces deux technologies ou sont-elles complémentaires? ... ou totalement différent?

Oswaldo
la source

Réponses:

185

En bref, ce sont des bibliothèques très différentes à des fins très différentes, mais oui, il y a de vagues similitudes.

Redux est un outil de gestion de l'état dans toute l'application. Il est généralement utilisé comme architecture pour les interfaces utilisateur. Considérez-le comme une alternative à (la moitié de) Angular.

RxJS est une bibliothèque de programmation réactive. Il est généralement utilisé comme un outil pour accomplir des tâches asynchrones en JavaScript. Pensez-y comme une alternative aux promesses.


La programmation réactive est un paradigme (façon de travailler et de penser) où les changements de données sont observés à distance . Les données ne sont pas modifiées à distance .

Voici un exemple de modification à distance :

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

Le modèle est modifié à partir du contrôleur.

Voici un exemple d' observation à distance :

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

Dans le Logger, nous observons les changements de données qui se produisent dans Store (à distance) et écrivons dans la console.


Redux utilise un peu le paradigme réactif: le Store est réactif. Vous ne définissez pas son contenu à distance. C'est pourquoi il n'y store.set()en a pas dans Redux. Le Store observe les actions à distance et se modifie. Et le Store permet aux autres d'observer ses données à distance.

RxJS utilise également le paradigme réactif, mais au lieu d'être une architecture, il vous donne des blocs de construction de base, les observables , pour accomplir ce modèle "d'observation à distance".

Pour conclure, des choses très différentes à des fins différentes, mais partager quelques idées.

André Staltz
la source
4
Non, vous ne devriez pas les utiliser ensemble. Les gens ont émulé Redux en utilisant Rx. Un rapide Google trouvera des exemples pour vous. Si vous souhaitez utiliser Rx pour votre interface utilisateur réactive, consultez Cycle.js, le framework d'André. Je l'utilise ces derniers temps et c'est fantastique. L'API a beaucoup changé récemment, mais je pense qu'il commence enfin à en geler certaines parties.
Joel Dentici
17
selon les documents officiels de redux , "Ils fonctionnent très bien ensemble".
galki le
12
Ils fonctionnent très bien ensemble! Il existe un middleware Redux qui vous donne la possibilité d'utiliser RxJS et Observables pour les actions Redux. github.com/redux-observable/redux-observable De plus, j'ai écrit un article de blog sur le How To: robinwieruch.de/redux-observable-rxjs
Robin Wieruch
1
Le paradigme Redux a contribué à rendre la base de code de mon projet Android plus réactive. Nos flux de données provenant de boutons et d'autres champs pour mettre à jour un état, en conjonction avec RxJava, ont suralimenté notre lisibilité et nos performances. Les bibliothèques vont certainement bien ensemble et leurs avantages sont indépendants de la langue.
Kenny Worden
Ils fonctionnent très bien ensemble, mais en pratique, Reactive peut faire pour vous ce que Redux ferait - synchroniser l'état de vos composants avec le modèle, si souvent cela n'a pas beaucoup de sens d'utiliser les deux
Filip Sobczak
32

Ce sont des choses très différentes.

RxJS peut être utilisé pour faire de la programmation réactive et est une bibliothèque très complète avec plus de 250 opérateurs.

Et Redux est comme décrit sur le dépôt github "Redux est un conteneur d'état prévisible pour les applications JavaScript".

Redux est juste un outil pour gérer l'état dans les applications. Mais en comparaison, vous pouvez créer une application complète en RxJS uniquement.

J'espère que cela t'aides :)

cmdv
la source
3
Votre réponse est bonne aussi @cmdv. Je ne l'ai pas vu quand j'écrivais le mien.
André Staltz
4

Redux est juste une bibliothèque de gestion d'état livrée avec des normes bien définies pour les opérations de mise à jour. Dans la mesure où vous vous en tenez aux normes, vous pouvez garder votre flux de données sain et facile à raisonner. Il permet également d'améliorer le flux de données avec des middlewares et des exhausteurs de magasin.

RxJS est une boîte à outils pour la programmation réactive. Vous pouvez réellement considérer tout ce qui se passe dans votre application comme un flux. RxJS offre un ensemble d'outils très riche pour gérer ces flux.

Où intercepte RxJS et Redux? En redux, vous mettez à jour votre état avec des actions et évidemment ces actions peuvent être traitées comme des flux. En utilisant un middleware comme redux-observable (vous n'êtes pas obligé), vous pouvez implémenter votre soi-disant "logique métier" de manière réactive. Une autre chose est que vous pouvez créer un observable à partir de votre magasin redux, ce qui peut parfois être plus facile que d'utiliser un enhancer.

mdikici
la source
2

Pour le dire en bref:

Redux: Bibliothèque inspirée de Flux utilisée pour la gestion des états .

RxJS: C'est une autre bibliothèque Javascript basée sur la philosophie de programmation réactive, utilisée pour traiter les "Streams" (Observables, etc.) [Lire la programmation réactive pour comprendre les concepts Stream].

Krishna Ganeriwal
la source
1

Je voulais juste ajouter quelques différences pragmatiques par rapport au moment où j'ai créé du code RxJS inspiré de Redux.

J'ai mappé chaque type d'action sur une instance de sujet. Chaque composant avec état aura un sujet qui est ensuite mappé dans une fonction de réduction. Tous les flux de réducteur sont combinés avec merge, puis scansortent l'état. La valeur par défaut est définie startWithjuste avant le scan. J'ai utilisé publishReplay(1)pour les états, mais je pourrais le supprimer plus tard.

La fonction react pure render sera uniquement le lieu où vous produisez des données d'événement en envoyant tous les producteurs / sujets.

Si vous avez des composants enfants, vous devez décrire comment ces états sont combinés dans le vôtre. combineLatestpourrait être un bon point de départ pour cela.

Différences notables dans la mise en œuvre:

  • Pas de middleware, juste des opérateurs rxjs. Je pense que c'est la plus grande puissance et faiblesse. Vous pouvez toujours emprunter des concepts, mais j'ai du mal à obtenir de l'aide de communautés sœurs comme redux et cycle.js car c'est encore une autre solution personnalisée. C'est pourquoi j'ai besoin d'écrire «je» au lieu de «nous» dans ce texte.

  • Aucun commutateur / boîtier ou chaînes pour les types d'action. Vous disposez d'une manière plus dynamique de séparer les actions.

  • rxjs peut être utilisé comme un outil ailleurs et n'est pas contenu dans la gestion des états.

  • Moins de producteurs que de types d'actions (?). Je ne suis pas sûr de cela, mais vous pouvez avoir de nombreuses réactions dans les composants parents qui écoutent les composants enfants. Cela signifie moins de code impératif et moins de complexité.

  • Vous possédez la solution. Aucun cadre nécessaire. Bon et mauvais. Vous finirez par écrire votre propre framework de toute façon.

  • C'est beaucoup plus fractal et vous pouvez facilement vous abonner aux modifications à partir d'un sous-arbre ou de plusieurs parties de l'arborescence d'état de l'application.

    • Devinez à quel point il est facile de faire des épopées comme le font redux-obseravble? Vraiment facile.

Je travaille également sur des avantages beaucoup plus importants où les composants enfants sont décrits comme des flux. Cela signifie que nous n'avons pas à compléter les états parent et enfant dans les réducteurs, puisque nous pouvons simplement ("juste") combiner récursivement les états en fonction de la structure du composant.

Je pense aussi à ne pas réagir et à aller avec snabbdom ou autre chose jusqu'à ce que React gère mieux les états réactifs. Pourquoi devrions-nous construire notre état vers le haut juste pour le décomposer à nouveau via des accessoires? Je vais donc essayer de faire une version 2 de ce pattern avec Snabbdom.

Voici un petit extrait de code plus avancé où le fichier state.ts construit le flux d'état. C'est l'état du composant de forme ajax qui obtient un objet de champs (entrées) avec des règles de validation et des styles css. Dans ce fichier, nous utilisons simplement les noms de champ (clés d'objet) pour combiner tous les états des enfants dans l'état du formulaire.

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
  }
}

Bien que le code ne dise pas grand-chose isolément, il montre comment vous pouvez créer un état vers le haut et comment vous pouvez produire facilement des événements dynamiques. Le prix à payer est que vous devez comprendre un style de code différent. Et j'aime payer ce prix.

Marcus Rådell
la source
C'est un an plus tard, je viens de trouver votre réponse et je pense qu'elle est toujours valable! J'ai fait quelque chose de similaire et je suis d'accord avec tous vos points. Mais une question quand même: pensez-vous toujours la même chose aujourd'hui ou avez-vous évolué depuis?
Xceno
1
Je dois réviser la critique sur les types de commutateur / cas et d'action dans Redux. Je continue de coder de la même manière, mais j'essaie de travailler sur la façon de le faire fonctionner côté serveur. En ce qui concerne le code React, j'ai réussi à faire un petit utilitaire qui aide à créer les réducteurs / mises à jour. Je fais donc toujours la même chose, mais un peu plus raffiné. Le plus gros changement est que je laisse chaque nœud feuille s'abonner au flux sur componentDidMount et me désabonner sur componentDidUnmount. Je souhaite également obtenir une couche de service réactive qui fonctionne sur le frontend et le backend. Faire des progrès là-bas.
Marcus Rådell