Pourquoi utiliser Redux sur Facebook Flux? [fermé]


1126

J'ai lu cette réponse , réduisant le passe-partout , regardé quelques exemples GitHub et même essayé un peu de redux (todo apps).

Si je comprends bien, les motivations officielles de doc redux fournissent des avantages par rapport aux architectures MVC traditionnelles. MAIS cela ne répond pas à la question:

Pourquoi devriez-vous utiliser Redux sur Facebook Flux?

Est-ce seulement une question de styles de programmation: fonctionnel vs non fonctionnel? Ou la question est dans les capacités / outils de développement qui découlent de l'approche redux? Peut-être une mise à l'échelle? Ou des tests?

Ai-je raison de dire que le redux est un flux pour les personnes issues de langages fonctionnels?

Pour répondre à cette question, vous pouvez comparer la complexité de la mise en œuvre des points de motivation de redux sur flux vs redux.

Voici les points de motivation des motivations officielles de redux doc :

  1. Gérer les mises à jour optimistes ( si je comprends bien, cela ne dépend guère du 5ème point. Est-il difficile de l'implémenter dans le flux facebook? )
  2. Rendu sur le serveur (le flux facebook peut également le faire. Des avantages par rapport au redux? )
  3. Récupération des données avant d'effectuer des transitions d'itinéraire ( Pourquoi cela ne peut-il pas être réalisé dans le flux Facebook? Quels sont les avantages? )
  4. Rechargement à chaud ( c'est possible avec React Hot Reload . Pourquoi avons-nous besoin de redux? )
  5. Fonctionnalité Annuler / Rétablir
  6. D'autres points? Comme un état persistant ...

73
Redux est une implémentation de "Facebook Flux". Flux n'est pas une bibliothèque ou un framework. Il s'agit simplement d'une architecture recommandée pour les applications Web. Je ne vois pas comment comparer une implémentation concrète avec le concept abstrait qui l'a motivée. L'implémentation réelle d'une architecture Flux par Facebook est Relay et la version open source n'en est encore qu'à ses débuts. facebook.github.io/relay
Charlie Martin

2
@CharlieMartin By FB Flux J'applique une application comme celle-ci github.com/facebook/flux/tree/master/examples . Mon projet actuel est écrit sur FB Flux (dû à FB Flux). Si vous le souhaitez, vous pouvez penser comme une architecture Redux sur une architecture FB Flux.
VB_

2
Je comprends maintenant. Vous voulez comparer l'exemple d'implémentation de Flux de Facebook avec l'implémentation de Flux de Redux
Charlie Martin

13
Relay n'est pas une implémentation de Flux - Relay / GraphQL est plus concerné par la gestion de l'extraction / interrogation de données avec le serveur tandis que Flux est principalement concerné par la structuration du flux de données entre les modèles de données côté client et les composants de vue. Cependant, il y a un certain chevauchement: chez Facebook, nous avons des applications entièrement construites en utilisant Flux, entièrement en utilisant Relay, ou avec les deux. Un modèle que nous voyons émerger est de laisser Relay gérer la majeure partie du flux de données pour une application, mais en utilisant les magasins Flux sur le côté pour gérer un sous-ensemble de l'état de l'application
Hal

Réponses:


1958

Auteur Redux ici!

Redux n'est pas si différent de Flux. Dans l'ensemble, il a la même architecture, mais Redux est capable de réduire certains coins de complexité en utilisant une composition fonctionnelle où Flux utilise l'enregistrement de rappel.

Il n'y a pas de différence fondamentale dans Redux, mais je trouve que cela rend certaines abstractions plus faciles, ou du moins possibles à implémenter, qui seraient difficiles ou impossibles à implémenter dans Flux.

Composition du réducteur

Prenez, par exemple, la pagination. Mon exemple Flux + React Router gère la pagination, mais le code est horrible. L'une des raisons pour lesquelles c'est horrible est que Flux rend peu naturel la réutilisation des fonctionnalités dans les magasins. Si deux magasins doivent gérer la pagination en réponse à des actions différentes, ils doivent soit hériter d'un magasin de base commun (mauvais! Vous vous enfermez dans une conception particulière lorsque vous utilisez l'héritage), soit appeler une fonction définie en externe à partir du gestionnaire d'événements, qui devra en quelque sorte opérer sur l'état privé du magasin Flux. Le tout est désordonné (bien que certainement dans le domaine du possible).

En revanche, avec Redux la pagination est naturelle grâce à la composition réductrice. Il s'agit de réducteurs jusqu'en bas, vous pouvez donc écrire une usine de réducteurs qui génère des réducteurs de pagination , puis l' utiliser dans votre arborescence de réducteurs . La raison pour laquelle c'est si facile est que dans Flux, les magasins sont plats, mais dans Redux, les réducteurs peuvent être imbriqués via la composition fonctionnelle, tout comme les composants React peuvent être imbriqués.

Ce modèle permet également des fonctionnalités merveilleuses telles que l' annulation / la restauration sans code utilisateur . Pouvez-vous imaginer brancher Undo / Redo dans une application Flux avec deux lignes de code? À peine. Avec Redux, c'est encore une fois, grâce au schéma de composition du réducteur. Je dois souligner qu'il n'y a rien de nouveau à ce sujet - c'est le modèle mis au point et décrit en détail dans Elm Architecture qui a lui-même été influencé par Flux.

Rendu du serveur

Les gens ont bien rendu sur le serveur avec Flux, mais vu que nous avons 20 bibliothèques Flux chacune essayant de rendre le rendu du serveur "plus facile", peut-être que Flux a des bords rugueux sur le serveur. La vérité est que Facebook ne fait pas beaucoup de rendu de serveur, ils ne se sont donc pas beaucoup inquiétés à ce sujet et comptent sur l'écosystème pour le rendre plus facile.

Dans Flux traditionnel, les magasins sont des singletons. Cela signifie qu'il est difficile de séparer les données pour différentes demandes sur le serveur. Pas impossible, mais difficile. C'est pourquoi la plupart des bibliothèques Flux (ainsi que les nouveaux Flux Utils ) vous suggèrent désormais d'utiliser des classes au lieu de singletons, afin que vous puissiez instancier des magasins par demande.

Il y a encore les problèmes suivants que vous devez résoudre dans Flux (vous-même ou avec l'aide de votre bibliothèque Flux préférée telle que Flummox ou Alt ):

  • Si les magasins sont des classes, comment puis-je les créer et les détruire avec le répartiteur par demande? Quand dois-je enregistrer les magasins?
  • Comment hydrater les données des magasins et les réhydrater ensuite sur le client? Dois-je implémenter des méthodes spéciales pour cela?

Certes, les frameworks Flux (pas Vanilla Flux) ont des solutions à ces problèmes, mais je les trouve trop compliqués. Par exemple, Flummox vous demande de l'implémenter serialize()et deserialize()dans vos magasins . Alt résout ce problème en fournissant takeSnapshot()une sérialisation automatique de votre état dans une arborescence JSON.

Redux va plus loin: puisqu'il n'y a qu'un seul magasin (géré par de nombreux réducteurs), vous n'avez pas besoin d'API spéciale pour gérer la (ré) hydratation. Vous n'avez pas besoin de «vider» ou «hydrater» les magasins - il n'y a qu'un seul magasin, et vous pouvez lire son état actuel ou créer un nouveau magasin avec un nouvel état. Chaque demande obtient une instance de magasin distincte. En savoir plus sur le rendu du serveur avec Redux.

Encore une fois, il s'agit de quelque chose de possible à la fois dans Flux et Redux, mais les bibliothèques Flux résolvent ce problème en introduisant une tonne d'API et de conventions, et Redux n'a même pas à le résoudre car il n'a pas ce problème dans le première place grâce à la simplicité conceptuelle.

Expérience développeur

Je n'avais pas vraiment l'intention que Redux devienne une bibliothèque Flux populaire - je l'ai écrite pendant que je travaillais sur mon exposé ReactEurope sur le rechargement à chaud avec le voyage dans le temps . J'avais un objectif principal: permettre de changer le code réducteur à la volée ou même «changer le passé» en biffant les actions, et voir l'état se recalculer.

Je n'ai vu aucune bibliothèque Flux capable de le faire. React Hot Loader ne vous permet pas non plus de le faire - en fait, il casse si vous modifiez les magasins Flux parce qu'il ne sait pas quoi en faire.

Lorsque Redux doit recharger le code réducteur, il appelle replaceReducer()et l'application s'exécute avec le nouveau code. Dans Flux, les données et les fonctions sont enchevêtrées dans les magasins Flux, vous ne pouvez donc pas «simplement remplacer les fonctions». De plus, il faudrait en quelque sorte réenregistrer les nouvelles versions avec Dispatcher, ce que Redux n'a même pas.

Écosystème

Redux possède un écosystème riche et à croissance rapide . En effet, il fournit quelques points d'extension tels que le middleware . Il a été conçu en tenant compte des cas d'utilisation tels que la journalisation , la prise en charge des promesses , des observables , du routage , des vérifications des développeurs d'immuabilité , la persistance , etc. Tout cela ne s'avérera pas utile, mais il est agréable d'avoir accès à un ensemble d'outils qui peuvent être facilement combinés pour fonctionner ensemble.

Simplicité

Redux conserve tous les avantages de Flux (enregistrement et relecture des actions, flux de données unidirectionnel, mutations dépendantes) et ajoute de nouveaux avantages (annulation facile à refaire, rechargement à chaud) sans introduire Dispatcher et l'enregistrement du magasin.

Il est important de rester simple, car il vous garde sain d'esprit pendant que vous implémentez des abstractions de niveau supérieur.

Contrairement à la plupart des bibliothèques Flux, la surface de l'API Redux est minuscule. Si vous supprimez les avertissements, commentaires et vérifications d'intégrité du développeur, c'est 99 lignes . Il n'y a pas de code asynchrone délicat à déboguer.

Vous pouvez le lire et comprendre tout Redux.


Voir aussi ma réponse sur les inconvénients de l'utilisation de Redux par rapport à Flux .


3
merci pour la réponse ... je suis nouveau dans js..dans votre réponse, vous avez dit que flux utilise un modèle de conception singleton ... pouvez-vous me dire en redux quel type de modèle de conception ils utilisent ... et dans flux peut vous me dites où ils utilisent le motif singleton ... pouvez-vous donner un exemple à la fois ... J'ai compris ce que fait le motif de conception d'ici singleton

2
J'ai commencé mon implémentation Android / Java (Fluxxan) basée sur Fluxxor (essentiellement du flux pur). Une fois que j'ai vu redux, j'ai été vendu. Il y a quelques portions que j'ai gardées purement flux mais, mec, ta bibliothèque est géniale!
frostymarvelous

5
Voulez-vous apprendre Redux? il suffit de regarder cette vidéo: youtube.com/watch?v=ucd5x3Ka3gw
gsalgadotoledo

5
Nous avons choisi que le redux soit beaucoup plus opiniâtre que le flux. Nous nous battions constamment pour savoir comment / où certains codes devraient aller, etc. Redux a supprimé toute cette confusion pour nous. Nous avons créé des applications avec redux pour le Web et React-Native et c'est incroyable !!
Quelque chose

1
La ligne github.com/reactjs/redux/blob/… était la réponse à la question que je cherchais depuis une semaine: comment structurer le magasin et les réducteurs, afin que plusieurs instances de composant réutilisable utilisées dans un contexte différent puissent être traitées sans duplication logique. La réponse semble être: utiliser trois niveaux de stockage en profondeur: 1er niveau: nom du composant ("pagination"), 2ème niveau: nom du conteneur ("stargazersByRepo"), 3 niveaux: la clé / id unique du conteneur ( ${login}/${name}). Merci beaucoup!
qbolec

101

À Quora, quelqu'un dit :

Tout d'abord, il est totalement possible d'écrire des applications avec React sans Flux.

Aussi ce diagramme visuel que j'ai créé pour montrer une vue rapide des deux, probablement une réponse rapide pour les personnes qui ne veulent pas lire toute l'explication: Flux vs Redux

Mais si vous souhaitez toujours en savoir plus, lisez la suite.

Je crois que vous devriez commencer par React pur, puis apprendre Redux et Flux. Une fois que vous aurez une VRAIE expérience avec React, vous verrez si Redux vous est utile ou non.

Peut-être vous sentirez-vous que Redux est exactement pour votre application et vous découvrirez peut-être que Redux essaie de résoudre un problème que vous ne rencontrez pas vraiment.

Si vous commencez directement avec Redux, vous risquez de vous retrouver avec du code sur-conçu, un code plus difficile à maintenir et avec encore plus de bogues et sans Redux.

Depuis les documents Redux :

Motivation
Comme les exigences pour les applications JavaScript d'une seule page sont devenues de plus en plus compliquées, notre code doit gérer plus d'états que jamais auparavant. Cet état peut inclure les réponses du serveur et les données mises en cache, ainsi que les données créées localement qui n'ont pas encore été conservées sur le serveur. L'état de l'interface utilisateur augmente également en complexité, car nous devons gérer les itinéraires actifs, les onglets sélectionnés, les filateurs, les contrôles de pagination, etc.

Gérer cet état en constante évolution est difficile. Si un modèle peut mettre à jour un autre modèle, une vue peut mettre à jour un modèle, ce qui met à jour un autre modèle, ce qui, à son tour, peut entraîner la mise à jour d'une autre vue. À un moment donné, vous ne comprenez plus ce qui se passe dans votre application, car vous avez perdu le contrôle de quand, pourquoi et comment son état. Lorsqu'un système est opaque et non déterministe, il est difficile de reproduire des bogues ou d'ajouter de nouvelles fonctionnalités.

Comme si cela ne suffisait pas, considérez que les nouvelles exigences deviennent courantes dans le développement de produits frontaux. En tant que développeurs, nous sommes censés gérer les mises à jour optimistes, le rendu côté serveur, la récupération des données avant d'effectuer des transitions de route, etc. Nous nous trouvons à essayer de gérer une complexité que nous n'avons jamais eu à affronter auparavant, et nous posons inévitablement la question: est-il temps d'abandonner? La réponse est non.

Cette complexité est difficile à gérer car nous mélangeons deux concepts très difficiles à raisonner pour l'esprit humain: la mutation et l'asynchronicité. Je les appelle Mentos et Coke. Les deux peuvent être formidables lorsqu'ils sont séparés, mais ensemble, ils créent un gâchis. Des bibliothèques comme React tentent de résoudre ce problème dans la couche de vue en supprimant à la fois l'asynchronie et la manipulation directe du DOM. Cependant, la gestion de l'état de vos données vous appartient. C'est là qu'intervient Redux.

Suivant les traces de Flux, CQRS et Event Sourcing, Redux tente de rendre les mutations d'état prévisibles en imposant certaines restrictions sur la manière et le moment où les mises à jour peuvent se produire. Ces restrictions se reflètent dans les trois principes de Redux.

Également à partir des documents Redux :

Concepts fondamentaux
Redux lui-même est très simple.

Imaginez que l'état de votre application soit décrit comme un simple objet. Par exemple, l'état d'une application todo peut ressembler à ceci:

{
  todos: [{
    text: 'Eat food',
    completed: true
  }, {
    text: 'Exercise',
    completed: false
  }],
  visibilityFilter: 'SHOW_COMPLETED'
}

Cet objet est comme un "modèle" sauf qu'il n'y a pas de setters. C'est ainsi que différentes parties du code ne peuvent pas changer l'état arbitrairement, provoquant des bogues difficiles à reproduire.

Pour changer quelque chose dans l'état, vous devez envoyer une action. Une action est un simple objet JavaScript (remarquez comment nous n'introduisons aucune magie?) Qui décrit ce qui s'est passé. Voici quelques exemples d'actions:

{ type: 'ADD_TODO', text: 'Go to swimming pool' }
{ type: 'TOGGLE_TODO', index: 1 }
{ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }

Faire en sorte que chaque changement soit décrit comme une action nous permet d'avoir une compréhension claire de ce qui se passe dans l'application. Si quelque chose a changé, nous savons pourquoi cela a changé. Les actions sont comme le fil d'Ariane de ce qui s'est passé. Enfin, pour lier l'état et les actions, nous écrivons une fonction appelée réducteur. Encore une fois, rien de magique à ce sujet - c'est juste une fonction qui prend l'état et l'action comme arguments, et retourne le prochain état de l'application. Il serait difficile d'écrire une telle fonction pour une grande application, nous écrivons donc des fonctions plus petites gérant des parties de l'état:

function visibilityFilter(state = 'SHOW_ALL', action) {
  if (action.type === 'SET_VISIBILITY_FILTER') {
    return action.filter;
  } else {
    return state;
  }
}

function todos(state = [], action) {
  switch (action.type) {
  case 'ADD_TODO':
    return state.concat([{ text: action.text, completed: false }]);
  case 'TOGGLE_TODO':
    return state.map((todo, index) =>
      action.index === index ?
        { text: todo.text, completed: !todo.completed } :
        todo
   )
  default:
    return state;
  }
}

Et nous écrivons un autre réducteur qui gère l'état complet de notre application en appelant ces deux réducteurs pour les clés d'état correspondantes:

function todoApp(state = {}, action) {
  return {
    todos: todos(state.todos, action),
    visibilityFilter: visibilityFilter(state.visibilityFilter, action)
  };
}

C'est fondamentalement toute l'idée de Redux. Notez que nous n'avons utilisé aucune API Redux. Il est livré avec quelques utilitaires pour faciliter ce modèle, mais l'idée principale est que vous décrivez comment votre état est mis à jour au fil du temps en réponse aux objets d'action, et 90% du code que vous écrivez est simplement du JavaScript, sans utiliser Redux lui-même, ses API ou toute magie.


57

Il vaut peut-être mieux commencer par lire cet article de Dan Abramov où il discute de diverses implémentations de Flux et de leurs compromis au moment où il écrivait redux: L'évolution des cadres de flux

Deuxièmement, cette page de motivations vers laquelle vous liez ne traite pas vraiment des motivations de Redux autant que des motivations derrière Flux (et React). Les trois principes sont plus spécifiques à Redux mais ne traitent toujours pas les différences de mise en œuvre de l'architecture Flux standard.

Fondamentalement, Flux possède plusieurs magasins qui calculent les changements d'état en réponse aux interactions UI / API avec les composants et diffusent ces changements en tant qu'événements auxquels les composants peuvent s'abonner. Dans Redux, il n'y a qu'un seul magasin auquel chaque composant est abonné. OMI, il semble au moins que Redux simplifie et unifie davantage le flux de données en unifiant (ou en réduisant, comme dirait Redux) le flux de données vers les composants - tandis que Flux se concentre sur l'unification de l'autre côté du flux de données - voir modèle.


27

Je suis un des premiers à adopter et à implémenter une application d'une seule page de taille moyenne à l'aide de la bibliothèque Facebook Flux.

Comme je suis un peu en retard dans la conversation, je vais juste souligner que malgré mes meilleurs espoirs, Facebook semble considérer leur mise en œuvre de Flux comme une preuve de concept et n'a jamais reçu l'attention qu'elle mérite.

Je vous encourage à jouer avec, car il expose davantage le fonctionnement interne de l'architecture Flux qui est assez pédagogique, mais en même temps, il ne fournit pas beaucoup des avantages que les bibliothèques comme Redux fournissent (qui ne sont pas cela est important pour les petits projets, mais il devient très précieux pour les plus grands).

Nous avons décidé que nous allons passer à Redux et je vous suggère de faire de même;)


Je développe l'application Facebook Flux depuis six mois. Et je ne sais toujours pas si un temps de migration vaut les avantages offerts par Redux. J'apprécierai tous vos commentaires sur les avantages / inconvénients de Redux sur le flux FB!
VB_

1
@VolodymyrBakhmatiuk pour nous, il s'agit principalement de réduire la quantité de passe-partout que nous devons écrire + une meilleure gestion des erreurs (redux crie par exemple si vous déclenchez une action qui n'a pas été définie dans votre liste constante - le flux FB ne le fera pas et il peut causer tout sortes de problèmes) Il y a quelques capacités plus avancées dans le flux, mais je ne les ai pas encore utilisées
Guy Nesher

1
@GuyNesher, une action non définie doit être détectée au moment de la compilation et non au moment de l'exécution. Flow (une autre contribution Facebook) vous permet de le faire.
Dominique PERETTI

@DominiquePERETTI - vrai (peut également utiliser des peluches) mais cela ne change pas le fait que ne pas détecter l'erreur au moment de l'exécution est un peu triste
Guy Nesher

J'ai écrit quelques aides simples pour gérer FBFlux, et il semble en fait que ce soit moins standardisé et configuré pour l'application que tous les exemples d'applications Redux que j'ai trouvés. A travaillé sur une application pendant plus de 9 mois entre deux développeurs et n'a jamais eu aucun problème avec l'architecture.
rob2d

20

Voici l'explication simple de Redux sur Flux. Redux n'a pas de répartiteur, il s'appuie sur des fonctions pures appelées réducteurs. Il n'a pas besoin d'un répartiteur. Chaque action est gérée par un ou plusieurs réducteurs pour mettre à jour le magasin unique. Étant donné que les données sont immuables, les réducteurs retournent un nouvel état mis à jour qui met à jour le magasinentrez la description de l'image ici

Pour plus d'informations Flux vs Redux


À propos de plusieurs magasins, est maintenant quelque chose faisable dans Redux, dans React-redux vous pouvez ajouter une clé pour isoler les magasins: redux.js.org/faq/storesetup échantillon de travail: github.com/Lemoncode/redux-multiple-stores
Braulio

6

J'ai travaillé assez longtemps avec Flux et maintenant assez longtemps avec Redux. Comme Dan l'a souligné, les deux architectures ne sont pas si différentes. Le fait est que Redux rend les choses plus simples et plus propres. Il vous apprend quelques choses en plus de Flux. Comme par exemple, Flux est un exemple parfait de flux de données unidirectionnel. Séparation des préoccupations lorsque nous avons des données, leurs manipulations et la couche de vue séparés. Dans Redux, nous avons les mêmes choses, mais nous apprenons également l'immuabilité et les fonctions pures.


5

D'un nouvel adoptant react / redux migrant depuis (quelques années) d'ExtJS mi-2018:

Après avoir reculé dans la courbe d'apprentissage redux, j'avais la même question et je pensais que le flux pur serait plus simple comme OP.

J'ai rapidement vu les avantages du redux sur le flux, comme indiqué dans les réponses ci-dessus, et je l'ai intégré dans ma première application.

Tout en reprenant le contrôle de la plaque de la chaudière, j'ai essayé quelques-unes des autres bibliothèques de gestion d'état, la meilleure que j'ai trouvée était la revanche .

C'était beaucoup plus intuitif que vanilla redux, cela coupe 90% du passe-partout et 75% du temps que je passais sur redux (quelque chose que je pense qu'une bibliothèque devrait faire), j'ai pu obtenir quelques applications d'entreprise aller tout de suite.

Il fonctionne également avec le même outillage redux. Ceci est un bon article qui couvre certains des avantages.

Donc, pour tous ceux qui sont arrivés à ce poste SO à la recherche de "redux plus simple", je recommande de l'essayer comme une alternative simple à redux avec tous les avantages et 1/4 du passe-partout.


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.