web-dev-qa-db-fra.com

Pourquoi utiliser Redux sur Facebook Flux?

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

Si je comprends bien, motivations officielles du document redux fournit des avantages comparés 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: fonctionnel ou non fonctionnel? Ou la question est dans les capacités/outils de développement qui découlent de l'approche redux? Peut-être mettre à l'échelle? Ou tester?

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

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

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

  1. Gestion des mises à jour optimistes (si je comprends bien, cela dépend à peine du cinquième point. Est-il difficile de l’implémenter dans Facebook Flux?)
  2. Rendu sur le serveur (facebook flux peut aussi le faire. Des avantages comparés à redux?)
  3. Récupérer des données avant d’effectuer des transitions d’itinéraire (Pourquoi cela n’est pas possible dans Facebook Flux? 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 l'état persistant ...
1126
VB_

L'auteur Redux ici!

Redux n'est pas celui différent de Flux. Globalement, elle a la même architecture, mais Redux est capable de résoudre certains problèmes de complexité en utilisant une composition fonctionnelle dans laquelle Flux utilise l’enregistrement de rappel.

Il n'y a pas de différence fondamentale dans Redux, mais je trouve que cela facilite certaines abstractions, ou du moins qu'il est possible de les implémenter, qu'il serait difficile voire impossible de les implémenter dans Flux.

Composition de réducteur

Prenons, par exemple, la pagination. Mon Flux + React exemple de routeur gère la pagination, mais le code correspondant est horrible. L'une des raisons pour lesquelles c'est horrible est que Flux rend réutilisation non-fonctionnelle des fonctionnalités entre magasins. Si deux magasins doivent gérer la pagination en réponse à des actions différentes, ils soit besoin d'hériter d'un magasin de base commun (mauvais! vous vous verrouillez dans une conception particulière lorsque vous utilisez l'héritage), soit d'appeler une fonction définie en externe à partir du gestionnaire d'événements, qui devra en quelque sorte opérer sur le disque privé du magasin Flux. Etat. Le tout est en désordre (bien que certainement dans le royaume du possible).

Par contre, avec Redux, la pagination est naturelle grâce à la composition réductrice. Les réducteurs sont tout en bas, vous pouvez donc écrire un ne usine de réducteurs générant des réducteurs de pagination puis à utiliser dans votre arborescence de réducteurs . La clé de la simplicité est 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 de superbes fonctionnalités telles que l’absence de code utilisateur annuler/rétablir . Pouvez-vous imaginer insérer deux lignes de code dans une application Flux? À peine. Avec Redux, c'est encore , grâce au motif de composition du réducteur. Je dois souligner qu’il n’ya rien de nouveau à ce sujet. C’est le modèle mis au point et décrit en détail dans Elm Architecture , lui-même influencé par Flux.

Rendu du serveur

Les gens ont bien rendu le serveur avec Flux, mais comme nous disposons de 20 bibliothèques Flux qui tentent toutes de rendre le rendu du serveur “plus facile”, Flux a peut-être des aspérités sur le serveur. La vérité est que Facebook ne fait pas beaucoup de rendu de serveur, ils ne sont donc pas très inquiets à ce sujet et comptent sur l'écosystème pour faciliter les choses.

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 le nouveau Flux Utils ) vous suggèrent maintenant d'utiliser des classes au lieu de singletons, afin que vous puissiez instancier des magasins à la demande.

Vous devez toujours résoudre les problèmes suivants dans Flux (soit vous-même, soit à 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 dispatch par requête? Quand dois-je enregistrer des magasins?
  • Comment puis-je 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 d'implémenter serialize() et deserialize() dans vos magasins . Alt résout ce problème en fournissant takeSnapshot() qui sérialise automatiquement votre état dans une arborescence JSON.

Redux va juste plus loin: puisqu'il n'y a qu'un seul magasin (géré par plusieurs 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 "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 demande 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 à la fois dans Flux et Redux, mais les bibliothèques de 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 à l’avenir. première place grâce à la simplicité conceptuelle.

Expérience de développeur

Je n'avais pas vraiment l'intention de faire de Redux une bibliothèque de flux très populaire - je l'ai écrite alors que je travaillais sur mon conférence ReactEurope sur le rechargement à chaud avec un voyage dans le temps . J'avais un objectif principal: permettre de changer le code du réducteur à la volée ou même de "changer le passé" en rayant les actions, et de voir l'état en cours de recalcul.

Je n'ai vu aucune bibliothèque Flux capable de le faire. React Hot Loader ne vous le permet pas non plus. En fait, il se brise si vous modifiez des magasins Flux, car ils ne savent 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 emmêlées dans les magasins Flux, vous ne pouvez donc pas "simplement remplacer les fonctions". De plus, il vous faudrait en quelque sorte réenregistrer les nouvelles versions avec Dispatcher - quelque chose que Redux n’a même pas.

Écosystème

Redux a un écosystème riche et à croissance rapide . En effet, il fournit quelques points d’extension tels que middleware . Il a été conçu avec des cas d'utilisation tels que journalisation , prise en charge de Promises , Observables , routage , immutabilité dev vérifie , persistance , etc., à l’esprit. Tous ne s’avéreront pas utiles, mais il est agréable d’avoir accès à un ensemble d’outils pouvant être facilement combinés pour fonctionner ensemble.

Simplicité

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

Garder les choses simples est important car cela 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, les commentaires et les vérifications de sécurité du développeur, c'est 99 lignes . Il n'y a pas de code asynchrone délicat à déboguer.

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


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

1959
Dan Abramov

À Quora, quelqu'un dit :

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

De plus, ce diagramme visuel que j'ai créé pour afficher une vue rapide des deux, probablement une réponse rapide pour les personnes qui ne veulent pas lire le explication complète: Flux vs Redux

Mais si vous êtes toujours intéressé à 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 expérience réelle de React, vous verrez si Redux vous est utile ou non.

Peut-être aurez-vous l’impression 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 démarrez directement avec Redux, vous risquez de vous retrouver avec un code trop technique, du code plus difficile à maintenir et avec encore plus de bogues et que sans Redux.

De documentation Redux :

Motivation
La configuration requise pour les applications JavaScript à une seule page étant de plus en plus complexe, 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. La complexité de l'état de l'interface utilisateur augmente également, car nous devons gérer les itinéraires actifs, les onglets sélectionnés, les filateurs, les contrôles de pagination, etc.

La gestion de 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, 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 de 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 communes dans le développement de produits front-end. En tant que développeurs, nous devons gérer les mises à jour optimistes, le rendu côté serveur, l'extraction de données avant d'effectuer des transitions d'itinéraire, etc. Nous essayons de gérer une complexité que nous n’avons jamais eu à traiter auparavant et nous posons inévitablement la question suivante: est-il temps d’abandonner? 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: la mutation et l'asynchronicité. Je les appelle Mentos et Coca-Cola. Les deux peuvent être très bien quand ils sont séparés, mais ensemble, ils créent un désordre. Des bibliothèques telles que React tentent de résoudre ce problème dans la couche de vue en supprimant les manipulations asynchrones et directes DOM. Cependant, la gestion de l'état de vos données est laissée à vous. 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 quant au mode et au moment où les mises à jour peuvent avoir lieu. Ces restrictions sont reflétées 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 soit décrit comme un objet simple. Par exemple, l'état d'une application à exécuter 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. Ainsi, différentes parties du code ne peuvent pas modifier l’état de manière arbitraire, ce qui entraîne des problèmes difficiles à reproduire.

Pour changer quelque chose dans l'état, vous devez envoyer une action. Une action est un objet JavaScript simple (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 idée claire de ce qui se passe dans l’application. Si quelque chose a changé, nous savons pourquoi. Les actions ressemblent à la chapelure 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 renvoie l'état suivant de l'application. Il serait difficile d'écrire une telle fonction pour une grosse application, nous écrivons donc des fonctions plus petites pour gérer 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 l’idée même 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écriviez comment votre état est mis à jour au fil du temps en réponse à des objets d’action, et que 90% du code que vous écrivez est constitué simplement de JavaScript, sans utilisation de Redux. lui-même, ses API, ou toute magie.

101
Alireza

Vous feriez peut-être mieux de commencer par lire cet article de Dan Abramov où il discute de différentes implémentations de Flux et de leurs compromis au moment où il écrivait redux: L’évolution des cadres de flux

Deuxièmement, la page des motivations vers laquelle vous créez un lien ne discute pas vraiment des motivations de Redux, mais des motivations derrière Flux (et React). Le Three Principles est plus spécifique à Redux mais ne traite toujours pas les différences de mise en œuvre par rapport à l'architecture standard de Flux.

Fondamentalement, Flux a plusieurs magasins qui calculent les changements d'état en réponse aux interactions UI/API avec les composants et diffusent ces modifications sous forme d'événements auxquels les composants peuvent s'abonner. Dans Redux, il n'y a qu'un seul magasin auquel chaque composant est abonné. IMO a au moins l'impression 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 - alors que Flux se concentre sur l'unification de l'autre côté du flux de données - vue vers modèle.

57
Hal

Je suis un des premiers à adopter et à mettre en place une application d'une page de taille moyenne à l'aide de la bibliothèque Facebook Flux.

Comme je suis un peu en retard dans la conversation, je tiens à souligner que, malgré mes meilleurs espoirs, Facebook semble considérer que leur implémentation de Flux est une preuve de concept et qu’elle n’a jamais reçu l’attention qu’elle mérite.

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

Nous avons décidé d’aller de l’avant vers Redux et je vous suggère de faire de même;)

27
Guy Nesher

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. Les données étant immuables, les réducteurs renvoient un nouvel état mis à jour qui met à jour le magasin enter image description here

Pour plus d'informations Flux vs Redux

20
Prathap Kudupu

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 sur Flux. Comme par exemple, Flux est un exemple parfait de flux de données dans une direction. Séparation des préoccupations lorsque nous avons des données, leurs manipulations et la couche de vue séparées. Dans Redux, nous avons les mêmes choses mais nous apprenons aussi sur l’immutabilité et les fonctions pures.

6
Krasimir

D'une nouvelle réaction/redux adoptant migrant de (quelques années) ExtJS à la mi-2018:

Après avoir glissé en arrière 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 vite vu les avantages de redux sur flux, comme indiqué dans les réponses ci-dessus, et je les travaillais dans ma première application.

Tout en reprenant la plaque de la chaudière à nouveau, j'ai essayé quelques unes des autres bibliothèques de gestion d'état, le meilleur que j'ai trouvé était rematch .

C'était beaucoup plus intuitif que le redux de Vanilla, il élimine 90% de la masse et réduit de 75% le temps que je passais à redux (quelque chose Je pense qu’une bibliothèque devrait le faire), j’ai pu lancer immédiatement quelques applications d’entreprise.

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 à cette SO post recherche "redux plus simple", je vous recommande de l'essayer comme alternative simple à redux avec tous les avantages et 1/4 du passe-partout.

5
Geronimo

Selon cet article: https://medium.freecodecamp.org/a-realworld-comparison-of-front-end-frameworks-with-benchmarks-2019-update-4be0d3c78075

Vous feriez mieux d'utiliser MobX pour gérer les données de votre application pour obtenir de meilleures performances, pas avec Redux.

0
yairniz