Qu'est-ce que Redux : Guide du concepteur

Publié: 2022-03-10
Résumé rapide ↬ Savez-vous que le véritable pouvoir de Redux va au-delà de la gestion de l'état ? Voulez-vous concevoir avec une compréhension du fonctionnement de Redux à l'esprit ? Approfondissons ce que Redux peut faire, pourquoi il fait ses choses, quels sont les inconvénients et comment il est lié à la conception.

Avez-vous entendu parler de Redux ? Qu'est-ce que c'est? Pas de recherche sur Google, s'il vous plaît !

  • "Des trucs de backend fantaisistes."
  • « J'en ai entendu parler, mais je ne sais pas ce que c'est. C'est peut-être un framework React ?
  • "Une meilleure façon de stocker et de gérer les états dans une application React."

J'ai posé cette question à plus de 40 designers. Ce qui précède sont leurs réponses typiques. Beaucoup d'entre eux savent que Redux fonctionne avec React et que son travail est la "gestion d'état".

Mais savez-vous ce que signifie vraiment cette « gestion de l'état » ? Savez-vous que le véritable pouvoir de Redux va au-delà de la gestion de l'État ? Savez-vous que Redux n'a pas forcément besoin de React pour fonctionner ? Voulez-vous rejoindre la discussion de votre équipe (ou au moins les discussions de déjeuner) sur l'opportunité d'utiliser Redux ? Voulez-vous concevoir avec une compréhension du fonctionnement de Redux à l'esprit ?

Avec l'aide de cet article, j'aimerais vous montrer une image complète de Redux : ce qu'il peut faire, pourquoi il fait ses choses, quels sont les inconvénients, quand l'utiliser et comment il est lié au design.

Mon but est d'aider les créateurs comme vous. Même si vous n'avez pas écrit une seule ligne de code auparavant, je pense qu'il est toujours possible et bénéfique (et amusant) de comprendre Redux. Attendez-vous à un anglais simple et à des griffonnages - pas de code ni de discussions abstraites.

Prêt pour la balade ?

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

Qu'est-ce que Redux ?

À un très haut niveau, Redux est un outil que les développeurs utilisent pour se simplifier la vie. Comme beaucoup d'entre vous l'ont peut-être entendu, son travail est la « gestion de l'État ». J'expliquerai ce que signifie la gestion d'état quelques sections plus loin. A ce stade, je vous laisse avec cette image :

Redux le gestionnaire d'état.
Redux gère l'état, mais en arrière-plan, il y a quelques pouvoirs cachés. (Illustration par Beebee) ( Grand aperçu )

Pourquoi devriez-vous vous en soucier ?

Redux concerne davantage le fonctionnement interne d'une application que son apparence. C'est un outil quelque peu complexe avec une courbe d'apprentissage abrupte. Cela signifie-t-il que nous, en tant que designers, devrions rester loin de cela ?

Non. Je pense que nous devrions l'accepter. Un concepteur automobile devrait comprendre à quoi sert le moteur, n'est-ce pas ? Pour concevoir avec succès des interfaces d'application, les concepteurs doivent également avoir de solides connaissances sur les éléments sous le capot . Nous devons en savoir plus sur ce qu'il peut faire, comprendre pourquoi les développeurs l'utilisent et être conscients de ses avantages et de ses implications.

« Le design n'est pas seulement ce à quoi il ressemble et ce à quoi il ressemble. Le design, c'est comme ça que ça marche.

—Steve Jobs

Que peut faire Redux ?

De nombreuses personnes utilisent Redux pour gérer l'état des applications React. C'est le cas d'utilisation le plus courant dans la nature et Redux améliore les aspects où React ne fonctionne pas (encore).

Cependant, vous verrez bientôt que le véritable pouvoir de Redux va bien au-delà. Commençons par apprendre ce que signifie vraiment la gestion de l'état.

Gestion de l'état

Si vous n'êtes pas sûr de la signification de cet « état », remplaçons-le par un terme plus générique : « données ». L'état est constitué de données qui changent de temps à autre . L'état détermine ce qui est affiché sur l'interface utilisateur.

Que signifie la gestion de l'État? En général, il y a trois aspects des données que nous devons gérer dans une application :

  1. Récupération et stockage des données
  2. Affectation de données aux éléments de l'interface utilisateur
  3. Modification des données

Disons que nous construisons une page de tir Dribbble. Quelles sont les données que nous voulons afficher sur la page ? Ils incluent la photo de profil de l'auteur, son nom, le GIF animé, le nombre de cœurs, les commentaires, etc.

Données sur une page de tir Dribbble
Données sur une page de tir Dribbble ( Grand aperçu )

Tout d'abord, nous devons récupérer toutes ces données à partir d'un serveur dans le cloud et les mettre quelque part. Ensuite, nous devons réellement afficher les données. Nous devons attribuer des parties de ces données aux éléments d'interface utilisateur correspondants qui représentent ce que nous voyons réellement dans le navigateur. Par exemple, nous attribuons l'URL de la photo de profil à l'attribut src d'une balise HTML img :

 <img src='https://url/to/profile_photo'>

Enfin, nous devons gérer les modifications apportées aux données. Par exemple, si un utilisateur ajoute un nouveau commentaire à un tir Dribbble ou ajoute une étoile, nous devons mettre à jour le code HTML en conséquence.

La coordination de ces trois aspects de l'état joue un rôle important dans le développement frontal, et React bénéficie de divers degrés de soutien pour cette tâche. Parfois, l'installation intégrée dans React fonctionne assez bien. Mais à mesure que l'application devient plus complexe, son état peut devenir plus difficile à gérer avec React seul. C'est pourquoi de nombreuses personnes commencent à utiliser Redux comme alternative.

Récupération et stockage de données

Dans React, nous décomposons une interface utilisateur en composants. Chacun de ces composants peut être décomposé en composants plus petits (voir "Qu'est-ce que React ?").

Page de tir de dribbble décomposée en composants
Page de tir Dribbble décomposée en composants ( Grand aperçu )

Si notre interface utilisateur est structurée de cette manière, quand récupérons-nous les données et où les stocker avant de remplir l'interface utilisateur ?

Imaginez qu'il y ait un chef vivant dans chaque composant . Récupérer les données des serveurs, c'est comme rechercher tous les ingrédients nécessaires à la préparation des plats.

Une méthode naïve consiste à récupérer et à stocker les données où et quand elles sont nécessaires. C'est comme si chaque chef sortait acheter des légumes et de la viande directement dans des fermes éloignées.

La méthode naïve : récupérez les données de chaque composant.
La méthode naïve : récupérez les données de chaque composant. (Illustration par Beebee) ( Grand aperçu )

Cette approche est inutile. Nous aurions besoin d'appeler le serveur plusieurs fois à partir de nombreux composants, même pour les mêmes données. Les chefs gaspilleraient beaucoup de gaz et de temps à faire des allers-retours.

Avec Redux, nous récupérons les données une seule fois et les stockons dans un endroit central, appelé « magasin ». Les données sont alors prêtes à être utilisées à tout moment par n'importe quel composant. Ce n'est pas sans rappeler d'avoir un supermarché à proximité où nos chefs peuvent acheter tous les ingrédients. L'hypermarché envoie des camions pour ramener les légumes et les viandes en vrac des fermes. C'est bien plus efficace que de demander à des chefs individuels de se rendre eux-mêmes dans les fermes !

Le magasin sert également de source unique de vérité. Les composants récupèrent toujours les données du magasin, et non d'ailleurs. Cela permet de conserver la cohérence de tout le contenu de l'interface utilisateur.

Redux comme magasin central de données.
Redux comme magasin central de données. (Illustration par Beebee) ( Grand aperçu )

Affectation de données aux éléments de l'interface utilisateur

Avec seulement React, il existe en fait un meilleur moyen de récupérer et de stocker des données. On peut demander à notre très gentil chef Shotwell de faire les courses pour tous ses amis chefs. Il conduisait un camion jusqu'aux fermes et rapportait les friandises. Nous pourrions récupérer des données à partir d'un composant de conteneur, par exemple, le composant "Shot" dans l'exemple Dribbble, et l'utiliser comme source unique de vérité.

Récupérez les données du composant racine.
Récupérez les données du composant racine. (Illustration par Beebee) ( Grand aperçu )

Cette approche est plus efficace que la manière naïve de récupérer les données de chaque composant. Mais comment Shotwell transmet-il les ingrédients aux autres chefs ? Comment transmettre les données aux composants qui affichent réellement les éléments HTML ? Nous transmettons les données des composants externes aux composants internes comme le bâton dans un relais, jusqu'à ce que les données atteignent la destination.

Par exemple, l'URL de l'avatar de l'auteur doit être passée de "Shot", à "ShotDetail", à "Title" et enfin à la <img> . Si nos chefs vivent dans un appartement, ça ressemble vraiment à ça :

Transmettez les données aux composants via des accessoires.
Transmettez les données aux composants via des accessoires. (Illustration par Beebee) ( Grand aperçu )

Pour livrer les données à la destination, nous devrions engager tous les composants sur le chemin, même s'ils n'ont pas du tout besoin des données. Ce serait vraiment ennuyeux s'il y avait plusieurs étages !

Et si l'hypermarché faisait de la livraison à domicile ? Avec Redux 1 , nous pouvons connecter n'importe quelle donnée à n'importe quel composant, sans affecter du tout les autres composants, comme ceci :

1 Pour être absolument précis, c'est une autre bibliothèque appelée react-redux qui transmet les données aux composants React, pas Redux lui-même. Mais puisque react-redux ne fait que la plomberie et que les gens utilisent presque toujours Redux et react-redux ensemble, je pense que c'est bien d'inclure cela comme l'un des avantages de Redux.

Connectez les données aux composants avec Redux.
Connectez les données aux composants avec Redux. (Illustration par Beebee) ( Grand aperçu )

Note : Dans la dernière version de React (16.3), il y a une nouvelle API "contexte" qui fait presque le même travail en termes de branchement de données dans des composants. Donc, si c'est la seule raison pour laquelle votre équipe utilise Redux, envisagez sérieusement de passer à React 16.3 ! Consultez le document officiel pour plus d'informations (attention : beaucoup de code à venir).

Modification des données

Parfois, la logique de mise à jour des données dans une application peut être assez complexe. Cela peut impliquer plusieurs étapes qui dépendent les unes des autres. Nous devrons peut-être attendre les réponses de plusieurs serveurs avant de mettre à jour l'état de l'application. Nous pourrions avoir besoin de mettre à jour de nombreux endroits de l'État à des moments différents et dans des conditions différentes.

Cela peut être écrasant si nous n'avons pas une bonne structure pour toute cette logique. Le code serait difficile à comprendre et à maintenir.

Redux nous permet de diviser pour régner . Il fournit un moyen standard de décomposer la logique de mise à jour des données en petits "réducteurs". Ces réducteurs travaillent harmonieusement ensemble pour compléter une action complexe.

Diviser la logique complexe en réducteurs.
Diviser la logique complexe en réducteurs. (Illustration par Beebee) ( Grand aperçu )

Gardez cependant un œil sur le développement récent de React. Comme pour l'API "contexte", il pourrait y avoir une nouvelle API "setState" dans une future version de React. Cela faciliterait la décomposition de la logique de mise à jour complexe en parties plus petites. Une fois cette nouvelle API disponible, il est possible que vous n'ayez plus besoin de Redux pour gérer cet aspect de la gestion des états.

La vraie puissance de Redux

Jusqu'à présent, il semble que Redux ne soit qu'un pansement pour React. Les gens utilisent Redux pour améliorer des aspects que React ne fait pas (encore) bien. Mais React se rattrape rapidement ! En fait, Dan Abramov, le créateur de Redux, a rejoint l'équipe principale de React chez Facebook il y a quelques années. Ils ont été occupés à travailler sur les améliorations susmentionnées de React : l'API contextuelle (publiée en 16.3), une meilleure API de récupération de données (démo en février 2018), une meilleure API setState, etc.

Cela rendra-t-il Redux obsolète ?

Devinez quoi? Je ne vous ai pas encore montré la vraie puissance de Redux !

La puissance Redux va bien au-delà de la gestion de l'état.
La puissance de Redux va bien au-delà de la gestion de l'état. (Illustration par Beebee) ( Grand aperçu )

Redux oblige les développeurs à suivre quelques règles strictes, qui apportent beaucoup de puissance à Redux (yup, la puissance de la discipline !) :

  1. Toutes les données (état de l'application) doivent être décrites en texte clair. Vous devriez être capable d'écrire toutes les données avec un stylo sur du papier.
  2. Chaque action (changement de données) doit être décrite en texte clair. Vous devez écrire ce que vous ferez avant de changer quoi que ce soit. Vous ne pouvez pas modifier les données sans laisser de marque. Ce processus est appelé "répartir une action" en argot Redux.
  3. Votre code qui modifie les données doit se comporter comme une formule mathématique. Il doit retourner le même résultat avec la même entrée. Le carré de 4 est toujours 16, peu importe combien de fois vous l'exécutez.

Lorsque vous suivez ces règles pour créer des applications, la magie opère. Il permet de nombreuses fonctionnalités intéressantes qui sont autrement difficiles ou coûteuses à mettre en œuvre. Voici quelques exemples. 2

2 J'ai rassemblé ces exemples dans le post de Dan Abramov "You Might Not Need Redux" et son "React Beginner Question Thread".

Défaire refaire

La fonctionnalité populaire d'annulation/rétablissement nécessite une planification au niveau du système. Étant donné que l'annulation/le rétablissement nécessite d'enregistrer et de rejouer chaque modification de données dans l'application, vous devez en tenir compte dans l'architecture dès le début. Si c'est fait après coup, cela nécessiterait de changer beaucoup de fichiers, ce qui est source d'innombrables bogues.

Défaire refaire.
Défaire refaire. (Illustration par Beebee) ( Grand aperçu )

Étant donné que Redux exige que chaque action soit décrite en texte clair, la prise en charge de l'annulation/rétablissement est presque gratuite. Les instructions sur la façon d'implémenter undo/redo avec Redux tiennent dans une simple page.

Environnement collaboratif

Si vous créez une application similaire à Google Docs où plusieurs utilisateurs travaillent ensemble sur une tâche complexe, envisagez d'utiliser Redux. Il fera probablement beaucoup d'haltérophilie pour vous.

Google Docs
Google Docs (Illustration par Beebee) ( Grand aperçu )

Redux permet d'envoyer très facilement ce qui se passe sur le réseau. Il est simple de recevoir les actions qu'un autre utilisateur effectue sur une autre machine, de rejouer les modifications et de fusionner avec ce qui se passe localement.

Interface utilisateur optimiste

L'interface utilisateur optimiste est un moyen d'améliorer l'expérience utilisateur d'une application. Cela donne l'impression que l'application répond plus rapidement sur un réseau lent. C'est une stratégie populaire dans les applications qui nécessitent des réponses en temps réel, par exemple, un jeu de tir à la première personne.

interface utilisateur optimiste
Interface utilisateur optimiste (Illustration par Beebee) ( Grand aperçu )

À titre d'exemple simple, dans l'application Twitter, lorsque vous cliquez sur le cœur d'un tweet, il doit demander au serveur de faire quelques vérifications, par exemple, si ce tweet existe toujours. Au lieu d'attendre plusieurs secondes pour le résultat, l'application choisit de tricher ! Il suppose que tout va bien et montre tout de suite un cœur rempli.

Coeur Twitter
Coeur Twitter (Illustration par Beebee) ( Grand aperçu )

Cette approche fonctionne car la plupart du temps, tout va bien. Lorsque les choses ne vont pas, l'application annulera les mises à jour précédentes de l'interface utilisateur et appliquera le résultat réel du serveur, par exemple, affichera un message d'erreur.

Redux prend en charge l'interface utilisateur optimiste de la même manière que ce qu'il fait pour annuler et rétablir. Il facilite l'enregistrement, la relecture et l'annulation des modifications de données lors de la réception d'un résultat négatif du serveur.

Persister et démarrer à partir de l'état

Redux permet de sauvegarder facilement ce qui se passe dans une application dans le stockage. Plus tard, même si l'ordinateur redémarre, l'application peut charger toutes les données et continuer exactement au même endroit, comme si elle n'avait jamais été interrompue.

Enregistrer/charger la progression du jeu
Enregistrer / charger la progression du jeu (Illustration par Beebee) ( Grand aperçu )

Si vous créez un jeu avec Redux, vous n'aurez besoin que de quelques lignes de code supplémentaires pour enregistrer/charger la progression du jeu, sans modifier le reste du code.

Systèmes vraiment extensibles

Avec Redux, vous devez "répartir" une action pour mettre à jour toutes les données d'une application. Cette restriction permet de se connecter à presque tous les aspects de ce qui se passe dans une application.

Vous pouvez créer des applications vraiment extensibles où chaque fonction peut être personnalisée par l'utilisateur. Par exemple, consultez Hyper, une application de terminal construite avec Redux. L'extension "hyperpower" ajoute des pépites au curseur et secoue la fenêtre. Aimez-vous ce mode "wow" ? (Peut-être pas très utile mais suffisant pour impressionner les utilisateurs)

Le mode "wow" dans Hyper, une application terminale.
Le mode "wow" dans Hyper, une application terminale. ( Grand aperçu )

Débogage du voyage dans le temps

Que diriez-vous de pouvoir voyager dans le temps lors du débogage d'une application ? Vous exécutez l'application, rembobinez ou avancez plusieurs fois pour trouver l'endroit exact où le bogue se produit, corrigez le bogue et rejouez pour confirmer.

Redux réalise ce rêve de développeurs. Redux DevTools vous permet de manipuler la progression d'une application en cours d'exécution comme une vidéo YouTube - en faisant glisser un curseur !

Comment ça marche? Vous souvenez-vous des trois règles strictes que Redux applique ? C'est la sauce secrète de la magie.

Voyage dans le temps dans Redux DevTools
Voyage dans le temps dans Redux DevTools Grand aperçu

Rapports de bogues automatisés

Imaginez ceci : un utilisateur trouve quelque chose qui ne va pas dans votre application et souhaite signaler le bogue. Elle se souvient et décrit minutieusement ce qu'elle a fait. Un développeur essaie ensuite de suivre les étapes manuellement pour voir si le bogue se reproduit. Le rapport de bogue peut être vague ou inexact. Le développeur a du mal à trouver où se trouve le bogue.

Maintenant, que diriez-vous de ceci. L'utilisateur clique sur le bouton "Signaler un bug". Le système envoie automatiquement ce qu'elle a fait au développeur. Le développeur clique sur le bouton "Rejouer le bogue" et regarde comment ce bogue se produit exactement. La bestiole est écrasée sur place, tout le monde est content !

C'est exactement ce qui se passerait si vous utilisiez Redux Bug Reporter. Comment ça marche? Les restrictions Redux font des merveilles.

Rapports de bugs automatisés
Rapports de bogues automatisés (Illustration par Beebee) ( Grand aperçu )

Inconvénients de Redux

Les trois règles principales appliquées par Redux sont une épée à double tranchant. Ils permettent des fonctionnalités puissantes, mais entraînent en même temps des inconvénients inévitables.

Courbe d'apprentissage abrupte

Redux a une courbe d'apprentissage relativement raide. Il faut du temps pour comprendre, mémoriser et s'habituer à ses schémas. Il n'est pas recommandé d'apprendre Redux et React en même temps s'ils sont nouveaux pour vous.

Code « passe-partout »

Dans de nombreux cas, utiliser Redux signifie écrire plus de code. Il est souvent nécessaire de toucher plusieurs fichiers pour faire fonctionner une fonctionnalité simple. Les gens se sont plaints du code « passe-partout » qu'ils devraient écrire avec Redux.

Je sais, cela semble contradictoire. N'ai-je pas dit que Redux permettait d'implémenter des fonctionnalités avec un minimum de code ? C'est un peu comme utiliser un lave-vaisselle. Tout d'abord, vous devrez passer du temps à organiser soigneusement les plats en rangées. Ce n'est qu'alors que vous verrez les avantages du lave-vaisselle : gain de temps sur le nettoyage de la vaisselle, la désinfection de la vaisselle, etc. Vous devez décider si le temps de préparation en vaut la peine !

Pénalité de performance

Redux pourrait également avoir un impact sur les performances en raison des restrictions qu'il applique. Cela ajoute un peu de surcharge chaque fois que les données changent. Dans la plupart des cas, ce n'est pas grave et le ralentissement n'est pas perceptible. Pourtant, lorsqu'il y a une grande quantité de données dans le magasin et que les données changent fréquemment (par exemple, lorsque l'utilisateur tape rapidement sur un appareil mobile), l'interface utilisateur peut devenir lente en conséquence.

Bonus : Redux n'est pas seulement pour réagir

Une idée fausse courante est que Redux est uniquement destiné à React. Il semble que Redux ne puisse rien faire sans React. En effet, Redux complète React de plusieurs manières importantes, comme nous en avons discuté précédemment. C'est le cas d'utilisation le plus courant.

Cependant, en fait, Redux peut fonctionner avec n'importe quel framework frontal, tel que Angular, Ember.js ou même jQuery, ou même du JavaScript vanille. Essayez de le googler, vous trouverez ceci, ceci, ceci ou même cela. Les idées générales de Redux s'appliquent partout !

Tant que vous utilisez Redux à bon escient, vous pouvez obtenir ses avantages dans de nombreuses situations, pas seulement dans une application React.

Redux fonctionne bien avec d'autres bibliothèques frontales
Redux fonctionne bien avec d'autres bibliothèques frontales. (Illustration par Beebee) ( Grand aperçu )

Conclusion

Comme tout outil, Redux offre un compromis. Il permet des fonctionnalités puissantes mais présente également des inconvénients inévitables. Le travail d'une équipe de développement consiste à évaluer si le compromis en vaut la peine et à prendre une décision consciente.

En tant que concepteurs, si nous comprenons les avantages et les inconvénients de Redux, nous pourrons contribuer à cette prise de décision du point de vue du design. Par exemple, peut-être pourrions-nous concevoir l'interface utilisateur pour atténuer l'impact potentiel sur les performances ? Peut-être pourrions-nous préconiser l'inclusion de fonctions d'annulation/rétablissement pour supprimer une multitude de boîtes de dialogue de confirmation ? Peut-être pourrions-nous suggérer une interface utilisateur optimiste car elle améliore l'expérience utilisateur avec un coût relativement faible ?

Comprendre les avantages et les limites d'une technologie et concevoir en conséquence. Je pense que c'est ce que Steve Jobs voulait dire par "le design, c'est comme ça que ça marche".