Redux · Une introduction

Publié: 2022-03-10
Résumé rapide ↬ Redux est l'une des bibliothèques les plus en vogue dans le développement front-end de nos jours. Cependant, beaucoup de gens ne savent pas ce que c'est et quels sont ses avantages. Comme l'indique la documentation, Redux est un conteneur d'état prévisible pour les applications JavaScript . Pour reformuler cela, il s'agit d'une architecture de flux de données d'application, plutôt que d'une bibliothèque traditionnelle ou d'un framework comme Underscore.js et AngularJS.

Redux est l'une des bibliothèques les plus en vogue dans le développement front-end de nos jours. Cependant, beaucoup de gens ne savent pas ce que c'est et quels sont ses avantages.

Comme l'indique la documentation, Redux est un conteneur d'état prévisible pour les applications JavaScript. Pour reformuler cela, il s'agit d'une architecture de flux de données d'application, plutôt que d'une bibliothèque traditionnelle ou d'un framework comme Underscore.js et AngularJS.

Lectures complémentaires sur SmashingMag

  • Pourquoi devriez-vous envisager React Native pour votre application mobile
  • Automatisation des tests pour les applications, les jeux et le Web mobile
  • Rendu côté serveur avec React, Node et Express
  • Remarques sur l'accessibilité rendue par le client

Redux a été créé par Dan Abramov vers juin 2015. Il s'inspire du flux de Facebook et du langage de programmation fonctionnel Elm. Redux est devenu populaire très rapidement en raison de sa simplicité , de sa petite taille (seulement 2 Ko) et de sa grande documentation. Si vous voulez apprendre comment Redux fonctionne en interne et plonger profondément dans la bibliothèque, pensez à consulter le cours gratuit de Dan.

Plus après saut! Continuez à lire ci-dessous ↓

Redux est principalement utilisé pour la gestion de l'état des applications. Pour résumer, Redux maintient l'état d'une application entière dans un seul arbre d'état immuable (objet), qui ne peut pas être modifié directement. Lorsque quelque chose change, un nouvel objet est créé (à l'aide d'actions et de réducteurs). Nous allons passer en revue les concepts de base en détail ci-dessous.

Quelle est la différence entre MVC et Flux ?

Pour donner une certaine perspective, prenons le modèle classique modèle-vue-contrôleur (MVC), puisque la plupart des développeurs le connaissent bien. Dans l'architecture MVC, il existe une séparation claire entre les données (modèle), la présentation (vue) et la logique (contrôleur). Il y a un problème avec cela, en particulier dans les applications à grande échelle : le flux de données est bidirectionnel. Cela signifie qu'une modification (une entrée utilisateur ou une réponse API) peut affecter l'état d'une application à de nombreux endroits dans le code, par exemple, la liaison de données bidirectionnelle. Cela peut être difficile à maintenir et à déboguer.

Flux est très similaire à Redux. La principale différence est que Flux dispose de plusieurs magasins qui modifient l'état de l'application et diffuse ces modifications sous forme d'événements. Les composants peuvent s'abonner à ces événements pour se synchroniser avec l'état actuel. Redux n'a pas de dispatcher , qui dans Flux est utilisé pour diffuser les charges utiles aux rappels enregistrés. Une autre différence dans Flux est que de nombreuses variétés sont disponibles, ce qui crée une certaine confusion et des incohérences.

Avantages de Redux

Vous vous demandez peut-être : "Pourquoi aurais-je besoin d'utiliser Redux ?" Excellente question. Il y a quelques avantages à utiliser Redux dans votre prochaine application :

  • Prévisibilité du résultat
    Il y a toujours une source de vérité, le magasin, sans confusion sur la façon de synchroniser l'état actuel avec les actions et les autres parties de l'application.
  • Maintenabilité
    Avoir un résultat prévisible et une structure stricte rend le code plus facile à maintenir.
  • Organisation
    Redux est plus strict sur la façon dont le code doit être organisé, ce qui rend le code plus cohérent et plus facile à utiliser pour une équipe.
  • Rendu serveur
    Ceci est très utile, en particulier pour le rendu initial, ce qui améliore l'expérience utilisateur ou l'optimisation des moteurs de recherche. Passez simplement le magasin créé sur le serveur au côté client.
  • Outils de développement
    Les développeurs peuvent suivre tout ce qui se passe dans l'application en temps réel, des actions aux changements d'état.
  • Communauté et écosystème
    C'est un énorme avantage chaque fois que vous apprenez ou utilisez une bibliothèque ou un framework. Avoir une communauté derrière Redux le rend encore plus attrayant à utiliser.
  • Facilité de test
    La première règle d'écriture de code testable est d'écrire de petites fonctions qui ne font qu'une chose et qui sont indépendantes. Le code de Redux est principalement constitué de fonctions qui ne sont que cela : petites, pures et isolées.

Programmation fonctionnelle

Comme mentionné, Redux a été construit sur des concepts de programmation fonctionnels. Comprendre ces concepts est très important pour comprendre comment et pourquoi Redux fonctionne comme il le fait. Passons en revue les concepts fondamentaux de la programmation fonctionnelle :

  • Il est capable de traiter les fonctions comme des objets de première classe.
  • Il est capable de passer des fonctions en arguments.
  • Il est capable de contrôler le flux à l'aide de fonctions, de récursions et de tableaux.
  • Il est capable d'utiliser des fonctions pures, récursives, d'ordre supérieur, de fermeture et anonymes.
  • Il est capable d'utiliser des fonctions d'assistance, telles que mapper, filtrer et réduire.
  • Il est capable d'enchaîner les fonctions.
  • L'état ne change pas (c'est-à-dire qu'il est immuable).
  • L'ordre d'exécution du code n'est pas important.

La programmation fonctionnelle nous permet d'écrire du code plus propre et plus modulaire. En écrivant des fonctions plus petites et plus simples dont la portée et la logique sont isolées, nous pouvons rendre le code beaucoup plus facile à tester, à maintenir et à déboguer. Maintenant, ces fonctions plus petites deviennent du code réutilisable , ce qui vous permet d'écrire moins de code, et moins de code est une bonne chose. Les fonctions peuvent être copiées et collées n'importe où sans aucune modification. Les fonctions dont la portée est isolée et qui n'exécutent qu'une seule tâche dépendront moins des autres modules d'une application, et ce couplage réduit est un autre avantage de la programmation fonctionnelle.

01-programmation-fonctionnelle-opt-preview
Exemple de programmation fonctionnelle (Image : Tanya Bachuk) (Voir la version agrandie)

Vous verrez des fonctions pures, des fonctions anonymes, des fermetures, des fonctions d'ordre supérieur et des chaînes de méthodes, entre autres, très souvent lorsque vous travaillez avec du JavaScript fonctionnel. Redux utilise beaucoup de fonctions pures, il est donc important de comprendre ce qu'elles sont.

Les fonctions pures renvoient une nouvelle valeur basée sur les arguments qui leur sont transmis. Ils ne modifient pas les objets existants ; au lieu de cela, ils en renvoient un nouveau. Ces fonctions ne dépendent pas de l'état à partir duquel elles sont appelées et elles ne renvoient qu'un seul et même résultat pour tout argument fourni. Pour cette raison, ils sont très prévisibles.

Étant donné que les fonctions pures ne modifient aucune valeur, elles n'ont aucun impact sur la portée ni aucun effet secondaire observable, ce qui signifie qu'un développeur peut se concentrer uniquement sur les valeurs renvoyées par la fonction pure.

Où Redux peut-il être utilisé ?

La plupart des développeurs associent Redux à React, mais il peut être utilisé avec n'importe quelle autre bibliothèque de vues. Par exemple, vous pouvez utiliser Redux avec AngularJS, Vue.js, Polymer, Ember, Backbone.js et Meteor. Redux plus React, cependant, reste la combinaison la plus courante. Assurez-vous d'apprendre React dans le bon ordre : le meilleur guide est celui de Pete Hunt, qui est très utile pour les développeurs qui débutent avec React et qui sont submergés par tout ce qui se passe dans l'écosystème. La fatigue JavaScript est une préoccupation légitime parmi les développeurs front-end, qu'ils soient nouveaux ou expérimentés, alors prenez le temps d'apprendre React ou Redux de la bonne manière dans le bon ordre.

L'une des raisons pour lesquelles Redux est génial est son écosystème. Ainsi, de nombreux articles, tutoriels, middleware, outils et passe-partout sont disponibles. Personnellement, j'utilise le passe-partout de David Zukowski car il contient tout ce dont on a besoin pour construire une application JavaScript, avec React, Redux et React Router. Un mot d'avertissement : essayez de ne pas utiliser de passe-partout et de kits de démarrage lors de l'apprentissage de nouveaux frameworks tels que React et Redux. Cela le rendra encore plus déroutant, car vous ne comprendrez pas comment tout fonctionne ensemble. Apprenez-le d'abord et créez une application très simple, idéalement en tant que projet parallèle, puis utilisez des passe-partout pour les applications de production afin de gagner du temps.

Construire des parties de Redux

Les concepts Redux peuvent sembler compliqués ou fantaisistes, mais ils sont simples. N'oubliez pas que la bibliothèque ne fait que 2 Ko. Redux a trois parties de construction : actions, magasin et réducteurs.

02-redux-data-flow-opt-preview
Flux de données Redux (Image : Tanya Bachuk) (Voir la version agrandie)

Discutons de ce que chacun fait.

Actions

En un mot, les actions sont des événements. Les actions envoient des données de l'application (interactions utilisateur, événements internes tels que les appels d'API et les soumissions de formulaire) au magasin. Le magasin obtient des informations uniquement à partir des actions. Les actions internes sont de simples objets JavaScript qui ont une propriété type (généralement constante), décrivant le type d'action et la charge utile des informations envoyées au magasin.

 { type: LOGIN_FORM_SUBMIT, payload: {username: 'alex', password: '123456'} }

Les actions sont créées avec des créateurs d'action. Cela semble évident, je sais. Ce ne sont que des fonctions qui renvoient des actions.

 function authUser(form) { return { type: LOGIN_FORM_SUBMIT, payload: form } }

Appeler des actions n'importe où dans l'application est donc très facile. Utilisez la méthode dispatch , comme ceci :

 dispatch(authUser(form));

Réducteurs

Nous avons déjà expliqué ce qu'est un réducteur en JavaScript fonctionnel. Il est basé sur la méthode de réduction de tableau, où il accepte un rappel (réducteur) et vous permet d'obtenir une valeur unique à partir de plusieurs valeurs, des sommes d'entiers ou une accumulation de flux de valeurs. Dans Redux, les reducers sont des fonctions (pures) qui prennent l'état actuel de l'application et une action, puis renvoient un nouvel état. Il est important de comprendre le fonctionnement des réducteurs car ils effectuent la majeure partie du travail. Voici un réducteur très simple qui prend l'état actuel et une action comme arguments, puis renvoie l'état suivant :

 function handleAuth(state, action) { return _.assign({}, state, { auth: action.payload }); }

Pour les applications plus complexes, l'utilisation de l' combineReducers() fourni par Redux est possible (en fait, recommandé). Il combine tous les réducteurs de l'application en un seul réducteur d'index. Chaque réducteur est responsable de sa propre partie de l'état de l'application, et le paramètre d'état est différent pour chaque réducteur. L' combineReducers() rend la structure du fichier beaucoup plus facile à maintenir.

Si un objet (état) ne change que certaines valeurs, Redux crée un nouvel objet, les valeurs qui n'ont pas changé feront référence à l'ancien objet et seules les nouvelles valeurs seront créées. C'est super pour les performances. Pour le rendre encore plus efficace, vous pouvez ajouter Immutable.js.

 const rootReducer = combineReducers({ handleAuth: handleAuth, editProfile: editProfile, changePassword: changePassword });

Boutique

Store est l'objet qui contient l'état de l'application et fournit quelques méthodes d'assistance pour accéder à l'état, envoyer des actions et enregistrer des écouteurs. L'état entier est représenté par un seul magasin. Toute action renvoie un nouvel état via des réducteurs. Cela rend Redux très simple et prévisible.

 import { createStore } from 'redux'; let store = createStore(rootReducer); let authInfo = {username: 'alex', password: '123456'}; store.dispatch(authUser(authInfo));

Outils de développement, voyage dans le temps et rechargement à chaud

Pour faciliter l'utilisation de Redux, en particulier lorsque vous travaillez avec une application à grande échelle, je recommande d'utiliser Redux DevTools. C'est incroyablement utile, montrant les changements d'état au fil du temps, les changements en temps réel, les actions et l'état actuel. Cela vous fait gagner du temps et des efforts en évitant l'état et les actions actuels de console.log .

03-redux-dev-tools-opt-preview
Redux DevTools (Voir la grande version)

Redux a une implémentation légèrement différente du voyage dans le temps que Flux. Dans Redux, vous pouvez revenir à un état antérieur et même prendre votre état dans une direction différente à partir de ce moment. Redux DevTools prend en charge les fonctionnalités de « voyage dans le temps » suivantes dans le flux de travail Redux (considérez-les comme des commandes Git pour votre état) :

  • Réinitialiser : réinitialise à l'état avec lequel votre boutique a été créée
  • Revert : revient au dernier état validé
  • Balayage : supprime toutes les actions désactivées que vous auriez pu déclencher par erreur
  • Commit : fait de l'état courant l'état initial

La fonction de voyage dans le temps n'est pas efficace en production et n'est destinée qu'au développement et au débogage. Il en va de même pour DevTools.

Redux rend les tests beaucoup plus faciles car il utilise le JavaScript fonctionnel comme base et les petites fonctions indépendantes sont faciles à tester. Ainsi, si vous devez modifier quelque chose dans votre arbre d'état, importez un seul réducteur responsable de cet état et testez-le de manière isolée.

Créer une application

Pour conclure ce guide d'introduction, construisons une application très simple en utilisant Redux et React. Pour que tout le monde puisse suivre plus facilement, je m'en tiendrai au bon vieux JavaScript, en utilisant ECMAScript 2015 et 2016 le moins possible. Nous continuerons la logique de connexion commencée plus tôt dans cet article. Cet exemple n'utilise aucune donnée en direct, car le but de cette application est de montrer comment Redux gère l'état d'une application très simple. Nous utiliserons CodePen.

1. Composant de réaction

Nous avons besoin de certains composants et données React. Créons un composant simple et affichons-le sur la page. Le composant aura un champ de saisie et un bouton (c'est un formulaire de connexion très simple). Ci-dessous, nous ajouterons du texte qui représente notre état :

Voir Pen Intro to Redux par Alex Bachuk (@abachuk) sur CodePen.

Voir Pen Intro to Redux par Alex Bachuk (@abachuk) sur CodePen.

2. Événements et actions

Ajoutons Redux au projet et gérons l'événement onClick pour le bouton. Dès que l'utilisateur se connecte, nous envoyons l'action avec le type LOGIN et la valeur de l'utilisateur actuel. Avant de pouvoir faire cela, nous devons créer un magasin et lui transmettre une fonction de réduction en tant qu'argument. Pour l'instant, le reducer sera juste une fonction vide :

Voir Pen Intro to Redux - Step 2. Events and Actions par Alex Bachuk (@abachuk) sur CodePen.

Voir Pen Intro to Redux - Step 2. Events and Actions par Alex Bachuk (@abachuk) sur CodePen.

3. Réducteurs

Maintenant que nous avons déclenché l'action, le réducteur prendra cette action et renverra un nouvel état. Gérons l'action LOGIN renvoyant un statut de connexion et ajoutons également une action LOGOUT , afin que nous puissions l'utiliser plus tard. Le réducteur auth accepte deux paramètres :

  1. l'état actuel (qui a la valeur par défaut),
  2. l'action.

Voir Pen Intro to Redux - Step 3. Reducers par Alex Bachuk (@abachuk) sur CodePen.

Voir Pen Intro to Redux - Step 3. Reducers par Alex Bachuk (@abachuk) sur CodePen.

4. Affichage de l'état actuel

Maintenant que nous avons l'état initial (la valeur par défaut dans reducer) et le composant React prêts, voyons à quoi ressemble l'état. Une bonne pratique consiste à pousser l'état vers les composants enfants. Comme nous n'avons qu'un seul composant, transmettons l'état de l'application en tant que propriété aux composants d' auth . Pour que tout fonctionne ensemble, nous devons enregistrer l'écouteur de magasin avec une méthode d'assistance d' subscribe , en enveloppant ReactDOM.render dans une fonction et en le passant à store.subscribe() :

Voir Pen Intro to Redux - Step 4. Affichage de l'état actuel par Alex Bachuk (@abachuk) sur CodePen.

Voir Pen Intro to Redux - Step 4. Affichage de l'état actuel par Alex Bachuk (@abachuk) sur CodePen.

5. Se connecter et se déconnecter

Maintenant que nous avons des gestionnaires d'action de connexion et de déconnexion, ajoutons un bouton de déconnexion et envoyons l'action LOGOUT . La dernière étape consiste à gérer le bouton pour afficher la connexion ou la déconnexion en déplaçant cette connexion en dehors de la méthode de rendu et en affichant la variable ci-dessous :

Voir Pen Intro to Redux - Step 5. Login/Logout par Alex Bachuk (@abachuk) sur CodePen.

Voir Pen Intro to Redux - Step 5. Login/Logout par Alex Bachuk (@abachuk) sur CodePen.

Conclusion

Redux gagne du terrain chaque jour. Il a été utilisé par de nombreuses entreprises (Uber, Khan Academy, Twitter) et dans de nombreux projets (Apollo, WordPress' Calypso), avec succès en production. Certains développeurs pourraient se plaindre qu'il y a beaucoup de frais généraux. Dans la plupart des cas, plus de code est nécessaire pour effectuer des actions simples telles que des clics de bouton ou de simples modifications de l'interface utilisateur. Redux n'est pas parfait pour tout. Il doit y avoir un équilibre. Peut-être que des actions simples et des modifications de l'interface utilisateur ne doivent pas nécessairement faire partie du magasin Redux et peuvent être maintenues au niveau des composants.

Même si Redux n'est peut-être pas la solution idéale pour votre application ou votre framework, je vous recommande vivement de le vérifier, en particulier pour les applications React.

Crédits image de la première page : Lynn Fisher, @lynnandtonic