Question Pourquoi utiliser Redux sur Facebook Flux?


j'ai lu cette réponse, réduction de la plaque chauffante, regardé quelques exemples de GitHub et même essayé de redux un peu (applications todo).

Tel que je le comprend, motivations officielles de redux doc Fournir des avantages par rapport aux architectures MVC traditionnelles. MAIS il ne fournit pas de réponse à la question:

Pourquoi devriez-vous utiliser Redux sur Facebook Flux? 

Est-ce seulement une question de styles de programmation: fonctionnelle vs non fonctionnelle? Ou la question est dans les capacités / dev-tools qui découlent de l'approche redux? Peut-être l'échelle? Ou tester?

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

Pour répondre à cette question, vous pouvez comparer la complexité des points de motivation de l'implémentation redux sur le flux et le redux.

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

  1. Gérer les mises à jour optimistes (si je comprends bien, cela dépend à peine du 5ème point. Est-ce difficile de l'implémenter dans facebook flux?)
  2. Rendu sur le serveur (flux facebook peut également le faire. Des avantages comparés à redux?)
  3. Récupérer des données avant d'effectuer des transitions de route (Pourquoi cela ne peut-il être réalisé en flux facebook? Quels sont les avantages?)
  4. Rechargement à chaud (C'est possible avec Réagissez Hot Reload. Pourquoi avons-nous besoin de redux?)
  5. Annuler / Rétablir les fonctionnalités
  6. D'autres points? Comme l'état persistant ...

1003
2017-09-08 15:05


origine


Réponses:


Redux auteur ici!

Redux n'est pas cette différent de Flux. Globalement, 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 qu'il rend certaines abstractions plus faciles, ou au moins possibles à implémenter, ce qui serait difficile ou impossible à implémenter dans Flux.

Composition de réducteur

Prenez, par exemple, la pagination. ma Flux + React Router exemple gère la pagination, mais le code pour cela est horrible. Une des raisons pour lesquelles c'est horrible est que Flux ne permet pas de réutiliser les fonctionnalités dans les magasins. Si deux magasins doivent gérer la pagination en réponse à différentes actions, ils doivent soit hériter d'un magasin de base commun (mauvais, vous vous enfermez dans un design particulier lorsque vous utilisez l'héritage), ou appeler une fonction du gestionnaire, qui devra fonctionner d'une manière ou d'une autre sur l'état privé du magasin Flux. Le tout est en désordre (bien que définitivement dans le domaine du possible).

D'autre part, avec Redux, la pagination est naturelle grâce à la composition du réducteur. C'est réducteurs tout le long, donc vous pouvez écrire un usine de réducteur qui génère des réducteurs de pagination et alors utilisez-le dans votre arbre réducteur. La clé pour expliquer pourquoi c'est si facile est parce que dans Flux, les magasins sont plats, mais dans Redux, les réducteurs peuvent être imbriqués via une composition fonctionnelle, tout comme les composants React peuvent être imbriqués.

Ce modèle permet également des fonctionnalités merveilleuses comme le code sans utilisateur défaire refaire. Pouvez-vous imaginer brancher Undo / Redo dans une application Flux en deux lignes de code? À peine. Avec Redux, c'estEncore, grâce au modèle de composition de réducteur. Je dois souligner qu'il n'y a rien de nouveau à ce sujet - c'est le modèle pionnier et décrit en détail dans Architecture d'orme 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 essayant chacune de rendre le rendu du serveur "plus facile", peut-être que Flux a quelques aspérités sur le serveur. La vérité est que Facebook ne fait pas beaucoup de rendu de serveur, donc ils n'ont pas été très préoccupés par cela, et comptent sur l'écosystème pour le rendre plus facile.

Dans le 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 la nouvelle Flux Utils) vous suggère maintenant d'utiliser des classes au lieu de singletons, de sorte que vous pouvez instancier des magasins par requête.

Il y a toujours les problèmes suivants que vous devez résoudre dans Flux (soit vous-même ou avec l'aide de votre bibliothèque Flux préférée, comme Démonter 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 puis-je hydrater les données des magasins et les réhydrater plus tard sur le client? Ai-je besoin de mettre en place des méthodes spéciales pour cela?

Certes, les frameworks Flux (pas de vanille Flux) ont des solutions à ces problèmes, mais je les trouve trop compliqués. Par exemple, Flummox vous demande de mettre en œuvre serialize() et deserialize() dans vos magasins. Alt résout ce plus agréable en fournissant takeSnapshot() cela sérialise automatiquement votre état dans un arbre JSON.

Redux va plus loin: Comme il n'y a qu'un seul magasin (géré par de nombreux réducteurs), vous n'avez besoin d'aucune API spéciale pour gérer la (ré) hydratation. Vous n'avez pas besoin de "vider" ou d '"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 requête obtient une instance de magasin distincte. En savoir plus sur le rendu du serveur avec Redux.

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

Expérience de développeur

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

Je n'ai pas vu une seule librairie de Flux capable de faire ça. React Hot Loader ne vous permet pas non plus de faire cela - 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 du réducteur, il appelle replaceReducer()et l'application fonctionne avec le nouveau code. Dans Flux, les données et les fonctions sont emmêlées dans les magasins Flux, vous ne pouvez donc pas "remplacer simplement les fonctions". De plus, vous devrez réenregistrer les nouvelles versions avec le Dispatcher - quelque chose que Redux n'a même pas.

Écosystème

Redux a un écosystème riche et en croissance rapide. C'est parce qu'il fournit quelques points d'extension tels que middleware. Il a été conçu avec des cas d'utilisation tels que enregistrement, soutien Promesses, Observables, routage, vérification de l'immutabilité, persistance, etc, à l'esprit. Tous ne se révéleront pas utiles, mais il est bon d'avoir accès à un ensemble d'outils qui peuvent facilement être combinés pour fonctionner ensemble.

Simplicité

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

Il est important de garder les choses simples car cela vous permet de rester sain pendant que vous implémentez des abstractions de plus haut niveau.

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

Vous pouvez réellement le lire et comprendre tout Redux.


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


1804
2017-10-03 08:26



A Quora, quelqu'un dit: 

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

Aussi cette diagramme visuel que j'ai créé montrent une vision 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 êtes toujours intéressé à en savoir plus, lisez la suite.

Je crois que vous devriez commencer avec React pur, puis apprendre Redux et Flux.   Après que vous aurez une expérience RÉELLE avec React, vous verrez   si Redux est utile pour vous ou non.

Peut-être que vous sentirez que Redux est exactement pour votre application et peut-être vous   va découvrir, que Redux essaie de résoudre un problème que vous n'êtes pas   vraiment l'expérience.

Si vous démarrez directement avec Redux, vous risquez de vous retrouver avec un sur-ingénierie   code, code plus difficile à maintenir et avec encore plus de bugs et que sans   Redux.

De Redux docs:

Motivation 
 Comme les exigences pour les applications mono-page JavaScript sont devenues de plus en plus complexes, notre   le code doit gérer plus d'état que jamais auparavant. Cet état peut inclure   réponses du serveur et des données mises en cache, ainsi que des données créées localement   n'a pas encore été persisté sur le serveur. L'état de l'interface utilisateur augmente également   en complexité, car nous devons gérer les routes actives, les onglets sélectionnés,   des filateurs, des commandes de pagination, et ainsi de suite.

Gérer cet état en constante évolution est difficile. Si un modèle peut être mis à jour   un autre modèle, puis une vue peut mettre à jour un modèle, qui met à jour un autre   modèle, et cela, à son tour, pourrait provoquer une autre vue à mettre à jour. À certains   point, vous ne comprenez plus ce qui se passe dans votre application comme vous l'avez   perdu le contrôle sur le quand, le pourquoi et le comment de son état. Quand un système   est opaque et non déterministe, il est difficile de reproduire des bugs ou d'ajouter   nouvelles fonctionnalités.

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

Cette complexité est difficile à gérer car nous mélangeons deux concepts   qui sont très difficiles à raisonner pour l'esprit humain: mutation et   asynchronicité. Je les appelle Mentos et Coca-Cola. Les deux peuvent être géniaux quand   séparés, mais ensemble, ils créent un gâchis. Des bibliothèques comme React   tenter de résoudre ce problème dans la couche de vue en supprimant les deux   asynchronie et manipulation directe du DOM. Cependant, gérer l'état de   Vos données vous sont laissées. C'est là que Redux entre en jeu.

Suivant les traces de Flux, CQRS et Event Sourcing, Redux   tente de rendre les mutations d'état prévisibles en imposant certains   restrictions sur comment et quand les mises à jour peuvent arriver. Ces restrictions   sont reflétés dans les trois principes de Redux.

Aussi de Redux docs:

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

Imaginez que l'état de votre application est décrit comme un objet simple. 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. Ce   est de sorte que les 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. Un   L'action est un simple objet JavaScript (remarquez comment nous n'introduisons aucun   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 un   compréhension claire de ce qui se passe dans l'application. Si quelque chose   changé, nous savons pourquoi cela a changé. Les actions sont comme la chapelure de   est arrivé. Enfin, pour lier l'état et les actions ensemble, nous écrivons   fonction appelée un réducteur. Encore une fois, rien de magique à ce sujet - c'est juste un   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 un   grande application, donc nous écrivons 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   app 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 essentiellement l'idée de Redux. Notez que nous n'avons pas utilisé   toutes les API Redux. Il est livré avec quelques utilitaires pour faciliter cette   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 à des objets d'action, et 90% du code   vous écrivez est tout simplement JavaScript, sans utiliser Redux lui-même, son   API, ou toute magie.


74
2018-03-22 12:59



Vous pourriez être mieux de commencer par lire ce post par Dan Abramov où il discute des différentes 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 que vous liez ne discute pas vraiment les motivations de Redux autant que les motivations derrière Flux (et React). le Trois principes est plus spécifique à Redux mais ne traite pas les différences d'implémentation par rapport à l'architecture Flux standard.

Fondamentalement, Flux a 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é. IMO au moins comme Redux simplifie encore et unifie le flux de données en unifiant (ou en réduisant, comme dirait Redux) le flux de données vers les composants - alors que Flux se concentre sur l'unification de l'autre côté du flux de données - vue à modèle.


50
2017-09-23 14:51



Je suis un des premiers utilisateurs et j'ai mis en place une application d'une seule page de taille moyenne en utilisant la bibliothèque Facebook Flux.

Comme je suis un peu en retard à la conversation, je ferai remarquer que malgré mes meilleurs espoirs, Facebook semble considérer leur implémentation de Flux comme une validation 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 de Flux qui est très instructif, mais en même temps il ne fournit pas beaucoup d'avantages que les bibliothèques comme Redux fournissent (qui ne sont pas cela est important pour les petits projets, mais devient très précieux pour les plus grands).

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


22
2018-01-05 13:45



Voici l'explication simple de Redux sur Flux. Redux n'a pas de répartiteur. Il repose 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. Puisque les données sont immuables, les réducteurs retournent un nouvel état mis à jour qui met à jour le magasin.enter image description here

Pour plus d'informations http://www.prathapkudupublog.com/2017/04/flux-vs-redux.html


13
2018-04-18 14:27



J'ai travaillé assez longtemps avec Flux et maintenant, je travaille beaucoup 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. Cela vous apprend quelques choses sur Flux. Comme par exemple, Flux est un exemple parfait de flux de données à sens unique. Séparation des préoccupations où nous avons des données, ses manipulations et vue couche séparée. En Redux nous avons les mêmes choses mais nous apprenons aussi l'immuabilité et les fonctions pures.


2
2018-01-25 12:26



Flux est un motif et Redux est une bibliothèque.

Flux est un nom fantaisiste pour le modèle d'observateur modifié légèrement pour s'adapter à React, mais Facebook a publié quelques outils pour aider à mettre en œuvre le modèle Flux, ce qui suit est la différence entre l'utilisation de ces outils ) et en utilisant Redux.

Flux et Redux ont tous deux des actions. Les actions peuvent être comparées à des événements (ou à des événements déclencheurs). Dans Flux, une action est un simple objet JavaScript, et c'est également le cas par défaut dans Redux, mais lorsque vous utilisez un middleware Redux, les actions peuvent également être des fonctions et des promesses.

Avec Flux c'est une convention d'avoir plusieurs magasins par application; chaque magasin est un objet singleton. Dans Redux, la convention est d'avoir un seul magasin par application, généralement séparé en domaines de données en interne (vous pouvez créer plus d'un magasin Redux si nécessaire pour des scénarios plus complexes).

Flux a un seul répartiteur et toutes les actions doivent passer par ce répartiteur. C'est un objet singleton. Une application Flux ne peut pas avoir plusieurs répartiteurs. Cela est nécessaire car une application Flux peut avoir plusieurs magasins et les dépendances entre ces magasins nécessitent un seul gestionnaire, à savoir le répartiteur.

Redux n'a pas d'entité de répartiteur. Au lieu de cela, le magasin a le processus d'expédition cuit dedans. Un magasin de Redux expose quelques fonctions d'API simples, l'un d'eux est d'expédier des actions.

Dans Flux, la logique de ce qu'il faut faire sur les données en fonction de l'action reçue est écrite dans le magasin lui-même. Le magasin a également la flexibilité de quelles parties des données à exposer publiquement. Le lecteur le plus intelligent dans une application Flux est le magasin.

En Redux, la logique de ce qu'il faut faire sur les données basées sur les actions reçues est dans la fonction réducteur qui est appelée pour chaque action qui est distribuée (via l'API du magasin). Un magasin ne peut pas être défini sans une fonction de réduction. Un réducteur Redux est une fonction simple qui reçoit l'état précédent et une action, et il retourne le nouvel état basé sur cette action. Dans une application Redux, vous pouvez diviser votre réducteur en fonctions plus simples comme vous le feriez avec n'importe quelle autre fonction. Le joueur le plus intelligent de Redux est le réducteur.

En Redux, aussi, il n'y a pas beaucoup de flexibilité sur ce qu'il faut exposer en tant qu'état du magasin. Redux va juste exposer tout ce qui revient du réducteur du magasin. C'est une contrainte.

L'autre plus grande contrainte est que l'état du magasin ne peut pas être mutable (ou vraiment, ne devrait pas l'être). Il n'y a pas de telle contrainte dans Flux, vous pouvez muter l'état comme vous le souhaitez. L'immutabilité de l'état, en Redux, est réalisée facilement en rendant les réducteurs purs (sans effets secondaires). Les réducteurs Redux copient toujours l'état qu'ils reçoivent et renvoie une version modifiée de la copie de l'état, pas l'objet original lui-même. Bien que ce soit une grosse contrainte, cela rend la vie beaucoup plus facile à long terme.


0
2018-06-24 07:13