Débuter avec Redux Pourquoi Redux?

Lorsque vous apprendrez à réagir, vous entendrez presque toujours dire à quel point Redux est formidable et que vous devriez l'essayer. L’écosystème React se développe à un rythme rapide et il y a tellement de bibliothèques sur lesquelles vous pouvez vous connecter, telles que flow, redux, middlewares, mobx, etc.. 

Apprendre à réagir est facile, mais il faut du temps pour s’habituer à l’ensemble de l’écosystème de React. Ce tutoriel est une introduction à l’un des composants essentiels de l’écosystème React: Redux..

Terminologie de base non-redux

Voici quelques terminologies couramment utilisées que vous ne connaissez peut-être pas, mais elles ne sont pas spécifiques à Redux en soi. Vous pouvez parcourir cette section et revenir ici quand / si quelque chose n'a pas de sens.  

Fonction pure

Une fonction pure est juste une fonction normale avec deux contraintes supplémentaires auxquelles elle doit satisfaire: 

  1. Étant donné un ensemble d'entrées, la fonction devrait toujours renvoyer la même sortie. 
  2. Il ne produit aucun effet secondaire.

Par exemple, voici une fonction pure qui renvoie la somme de deux nombres.

/ * Pure add fonction * / const add = (x, y) => retour x + y;  console.log (add (2,3)) // 5 

Les fonctions pures donnent un résultat prévisible et sont déterministes. Une fonction devient impure lorsqu'elle effectue autre chose que le calcul de sa valeur de retour. 

Par exemple, la fonction add ci-dessous utilise un état global pour calculer sa sortie. En outre, la fonction enregistre également la valeur dans la console, ce qui est considéré comme un effet secondaire.. 

const y = 10; const impureAdd = (x) => console.log ('Les entrées sont $ x et $ y'); renvoyer x + y;  

Effets secondaires observables

"Effets secondaires observables" est un terme sophistiqué désignant les interactions créées par une fonction avec le monde extérieur. Si une fonction tente d'écrire une valeur dans une variable qui existe en dehors de la fonction ou tente d'appeler une méthode externe, vous pouvez appeler en toute sécurité ces effets secondaires. 

Cependant, si une fonction pure appelle une autre fonction pure, elle peut être traitée comme pure. Voici quelques-uns des effets secondaires courants:

  • faire des appels API
  • se connecter à la console ou imprimer des données
  • données en mutation
  • Manipulation DOM
  • récupérer l'heure actuelle

Conteneur et composants de présentation

Il est utile de scinder l'architecture des composants en deux lorsque vous travaillez avec des applications React. Vous pouvez les classer en deux catégories: les composants de conteneur et les composants de présentation. Ils sont également connus sous le nom de composants intelligents et stupides. 

Le composant conteneur concerne le fonctionnement des éléments, tandis que les composants de présentation concernent leur apparence. Pour mieux comprendre les concepts, j'ai abordé cela dans un autre tutoriel: Conteneur vs Composants de présentation dans React.

Objets mutables ou immuables

Un objet mutable peut être défini comme suit:

UNE objet mutable est un objet dont l'état peut être modifié après sa création.

L’immuabilité est exactement le contraire: un objet immuable est un objet dont l’état ne peux pas être modifié après sa création. En JavaScript, les chaînes et les nombres sont immuables, mais les objets et les tableaux ne le sont pas. L'exemple montre mieux la différence. 

/ * Les chaînes et les nombres sont immuables * / let a = 10; soit b = a; b = 3; console.log ('a = $ a et b = $ b'); // a = 10 et b = 3 / * Mais les objets et les tableaux ne sont pas * / / * Commençons par les objets * / let user = name: "Bob", 22 ans, job: "Aucun" utilisateur_actif = utilisateur ; utilisateur_actif.nom = "Tim"; // Les deux objets ont la même valeur console.log (utilisateur_actif); // "nom": "Tim", "age": 22, "travail": "Aucun" console.log (utilisateur); // "name": "Tim", "age": 22, "job": "None" / * Maintenant pour les tableaux * / let usersId = [1,2,3,4,5] laisser usersIdDup = usersId ; usersIdDup.pop (); console.log (usersIdDup); // [1,2,3,4] console.log (usersId); // [1,2,3,4]

Pour rendre les objets immuables, utilisez le Object.assign méthode pour créer une nouvelle méthode ou l'opérateur tout nouveau spread.

let user = name: "Bob", âge: 22 ans, job: "Aucun" utilisateur_actif = Object.assign (, utilisateur, name: "Tim") console.log (utilisateur); // "nom": "Bob", "age": 22, "travail": "Aucun" console.log (utilisateur_actif); // "nom": "Tim", "âge": 22, "travail": "Aucun" 

Qu'est-ce que Redux??

La page officielle définit Redux comme suit:

Redux est un conteneur d'état prévisible pour les applications JavaScript. 

Bien que cela décrit avec précision Redux, il est facile de se perdre lorsque vous voyez pour la première fois une image plus grande de Redux. Il y a tellement de pièces en mouvement que vous devez assembler. Mais une fois que vous le ferez, je vous promets que vous commencerez à aimer Redux.. 

Redux est une bibliothèque de gestion d'état que vous pouvez connecter à n'importe quelle bibliothèque JavaScript, et pas seulement à React. Cependant, cela fonctionne très bien avec React en raison de la nature fonctionnelle de React. Pour mieux comprendre cela, regardons l'état.

Comme vous pouvez le constater, l'état d'un composant détermine ce qui est rendu et son comportement. L'application a un état initial et toute interaction de l'utilisateur déclenche une action mettant à jour l'état. Lorsque l'état est mis à jour, la page est rendue.

Avec React, chaque composant a un état local accessible depuis l'intérieur du composant. Vous pouvez également le transmettre en tant que support aux composants enfants. Nous utilisons habituellement l'état pour stocker:

  1. État de l'interface utilisateur et données transitoires. Ceci inclut une liste d’éléments d’interface utilisateur pour les entrées de menu ou de formulaire de navigation dans un composant contrôlé..
  2. Etat de l'application tel que les données extraites d'un serveur, l'état de connexion de l'utilisateur, etc..

Le stockage de données d'application dans l'état d'un composant est correct lorsque vous disposez d'une application React de base avec quelques composants.. 

Hiérarchie des composants d'une application de base

Cependant, la plupart des applications réelles auront beaucoup plus de fonctionnalités et de composants. Lorsque le nombre de niveaux dans la hiérarchie des composants augmente, la gestion de l'état devient problématique. 

Esquisse d'une application de taille moyenne

Pourquoi devriez-vous utiliser Redux?

Voici un scénario très probable que vous pourriez rencontrer en travaillant avec React.

  1. Vous construisez une application de taille moyenne et vos composants sont clairement divisés en composants simples et intelligents.. 
  2. Les composants intelligents gèrent l'état, puis les transmettent aux composants muets. Ils s’occupent d’appeler des API, d’extraire les données de la source de données, de les traiter, puis de définir l’état. Les composants muets reçoivent les accessoires et renvoient la représentation de l'interface utilisateur. 
  3. Lorsque vous êtes sur le point d'écrire un nouveau composant, il n'est pas toujours clair où placer l'état. Vous pouvez laisser l'état faire partie d'un conteneur qui est un parent immédiat du composant de présentation. Mieux encore, vous pouvez déplacer l'état plus haut dans la hiérarchie afin qu'il soit accessible à plusieurs composants de présentation..
  4. Lorsque l'application grandit, vous voyez que l'état est dispersé partout. Lorsqu'un composant doit accéder à un état auquel il n'a pas immédiatement accès, vous essayez de le remonter jusqu'à l'ancêtre du composant le plus proche.. 
  5. Après un refactoring et un nettoyage constants, vous vous retrouvez avec la plupart des places détenues par l'état en haut de la hiérarchie des composants.. 
  6. Enfin, vous décidez qu’il est judicieux de laisser un composant en haut gérer l’état de manière globale, puis de tout transmettre. Chaque autre composant peut souscrire aux accessoires dont ils ont besoin et ignorer le reste.

C’est ce que j’ai personnellement expérimenté avec React et de nombreux autres développeurs seront d’accord. React est une bibliothèque de vues et ce n'est pas le travail de React de gérer spécifiquement l'état. Ce que nous recherchons, c'est le principe de séparation des préoccupations. 

Redux vous aide à séparer l'état de l'application de React. Redux crée un magasin global qui réside au plus haut niveau de votre application et transmet l'état à tous les autres composants. Contrairement à Flux, Redux ne possède pas plusieurs objets de magasin. L'état complet de l'application se trouve dans cet objet magasin et vous pouvez éventuellement permuter la couche de vue avec une autre bibliothèque dont le magasin est intact..

Les composants sont restitués chaque fois que le magasin est mis à jour, avec un impact très faible sur les performances. C'est une bonne nouvelle et cela apporte de nombreux avantages. Vous pouvez traiter tous vos composants React comme des imbéciles, et React peut se concentrer uniquement sur le point de vue de la visualisation..

Maintenant que nous savons pourquoi Redux est utile, passons à l'architecture Redux.

L'architecture Redux

Lorsque vous apprenez Redux, vous devez vous familiariser avec quelques concepts de base. L'image ci-dessous décrit l'architecture Redux et comment tout est connecté. 

Redux en quelques mots

Si vous êtes habitué à Flux, certains éléments peuvent vous paraître familiers. Sinon, ça va aussi parce que nous allons tout couvrir depuis la base. Tout d’abord, assurez-vous que vous avez installé redux:

npm installer redux

Utilisez create-react-app ou votre configuration webpack préférée pour configurer le serveur de développement. Étant donné que Redux est un gestionnaire d’État indépendant, nous n’allons pas encore nous connecter à React. Supprimez donc le contenu de index.js, et nous jouerons avec Redux pour la suite de ce tutoriel..

le magasin

Le magasin est un grand objet JavaScript qui contient des tonnes de paires clé-valeur qui représentent l'état actuel de l'application. Contrairement à l'objet d'état dans React qui est réparti sur différents composants, nous n'avons qu'un seul magasin. Le magasin fournit l’état de l’application et chaque fois que l’état est mis à jour, la vue est rendue. 

toutefois, vous ne pouvez jamais muter ou changer de magasin. Au lieu de cela, vous créez de nouvelles versions du magasin. 

(previousState, action) => newState

De ce fait, vous pouvez voyager dans le temps dans tous les états à partir du moment où l'application a été démarrée sur votre navigateur..

Le magasin dispose de trois méthodes pour communiquer avec le reste de l’architecture. Elles sont:

  • Store.getState () - Pour accéder à l’arbre d’état actuel de votre application. 
  • Store.dispatch (action) -Pour déclencher un changement d'état basé sur une action. En savoir plus sur les actions ci-dessous.
  • Store.subscribe (listener) -Pour écouter tout changement d'état. Il sera appelé chaque fois qu'une action est envoyée.

Créons un magasin. Redux a un createStore méthode pour créer un nouveau magasin. Vous devez passer un réducteur, bien que nous ne sachions pas ce que c'est. Je vais donc créer une fonction appelée réducteur. Vous pouvez éventuellement spécifier un deuxième argument qui définit l'état initial du magasin.. 

src / index.js

importer createStore de "redux"; // Ceci est le réducteur const réducteur = () => / * Quelque chose se passe ici * / // initialState est facultatif. // Pour cette démonstration, j'utilise un compteur, mais l'état est généralement un objet const initialState = 0 const store = createStore (réducteur, initialState);

Maintenant, nous allons écouter tous les changements dans le magasin, puis console.log () l'état actuel du magasin.

store.subscribe (() => console.log ("L’État a changé" + store.getState ());) 

Alors, comment pouvons-nous mettre à jour le magasin? Redux a quelque chose appelé des actions qui rendent cela possible.

Action / Créateurs d'action

Les actions sont également des objets JavaScript simples qui envoient des informations de votre application au magasin. Si vous avez un compteur très simple avec un bouton d'incrémentation, une action déclenchera une action qui ressemblera à ceci:

type: "INCREMENT", charge utile: 1

Ils sont la seule source d’information pour le magasin. L'état de la banque ne change qu'en réponse à une action. Chaque action doit avoir une propriété type qui décrit ce que l'objet action a l'intention de faire. Autre que cela, la structure de l'action est entièrement à vous. Cependant, gardez votre petite action car une action représente la quantité minimale d'informations requise pour transformer l'état de l'application.. 

Par exemple, dans l'exemple ci-dessus, la propriété type est définie sur "INCREMENT" et une propriété supplémentaire de charge utile est incluse. Vous pouvez renommer la propriété payload en quelque chose de plus significatif ou, dans notre cas, l'omettre entièrement. Vous pouvez envoyer une action au magasin comme ceci.

store.dispatch (type: "INCREMENT", charge utile: 1); 

Lors du codage de Redux, vous n’utiliserez normalement pas d’actions directement. Au lieu de cela, vous appellerez des fonctions qui renvoient des actions. Ces fonctions sont communément appelées créateurs d’actions. Voici le créateur de l'action d'incrémentation dont nous avons parlé précédemment.

const incrementCount = (count) => return type: "INCREMENT", charge utile: count

Donc, pour mettre à jour l’état du compteur, vous devrez envoyer le incrementCount action comme celle-ci:

store.dispatch (incrementCount (1)); store.dispatch (incrementCount (1)); store.dispatch (incrementCount (1));

Si vous vous dirigez vers la console du navigateur, vous verrez qu'il fonctionne partiellement. Nous sommes indéfinis parce que nous n'avons pas encore défini le réducteur.

Alors maintenant, nous avons couvert les actions et le magasin. Cependant, nous avons besoin d'un mécanisme pour convertir les informations fournies par l'action et transformer l'état du magasin. Les réducteurs servent à cette fin.

Réducteurs

Une action décrit le problème et le réducteur est responsable de la résolution du problème. Dans l'exemple précédent, le incrementCount La méthode retournée une action qui a fourni des informations sur le type de changement que nous voulions apporter à l'état. Le réducteur utilise ces informations pour mettre à jour l'état. Il y a un gros point souligné dans la documentation que vous devriez toujours vous rappeler lorsque vous utilisez Redux:

Compte tenu des mêmes arguments, un réducteur devrait calculer le prochain état et le renvoyer. Pas de surprises. Pas d'effets secondaires. Aucun appel d'API. Pas de mutations. Juste un calcul.

Cela signifie qu'un réducteur doit être une fonction pure. Étant donné un ensemble d'entrées, il devrait toujours renvoyer la même sortie. Au-delà, cela ne devrait plus rien faire. En outre, un réducteur n'est pas l'endroit idéal pour des effets secondaires tels que les appels AJAX ou l'extraction de données à partir de l'API.. 

Remplissons le réducteur pour notre comptoir.

// Ceci est le réducteur const réducteur = (state = initialState, action) => switch (action.type) case "INCREMENT": return state + action.payload défaut: return state

Le réducteur accepte deux arguments, state et action, et renvoie un nouvel état..

(previousState, action) => newState

L’état accepte une valeur par défaut, le Etat initial, qui ne sera utilisé que si la valeur de l'état est indéfinie. Sinon, la valeur réelle de l'état sera conservée. Nous utilisons l'instruction switch pour sélectionner la bonne action. Actualisez le navigateur et tout fonctionne comme prévu. 

Ajoutons un cas pour DECREMENT, sans quoi le compteur est incomplet.

// C'est le réducteur const réducer = (state = initialState, action) => switch (action.type) case "INCREMENT": return state + action.payload case "DECREMENT": return state - action.payload par défaut: état de retour

Voici le créateur d'action.

const decrementCount = (count) => return type: "DECREMENT", charge utile: compte

Enfin, expédiez-le au magasin.

store.dispatch (incrementCount (4)); // 4 store.dispatch (decrementCount (2)); // 2

C'est tout!

Résumé

Ce tutoriel devait être un point de départ pour la gestion d’état avec Redux. Nous avons couvert tous les éléments essentiels nécessaires à la compréhension des concepts de base de Redux, tels que le magasin, les actions et les réducteurs. Vers la fin du didacticiel, nous avons également créé un compteur de démonstration Redux en état de marche. Bien que ce ne soit pas beaucoup, nous avons appris comment toutes les pièces du puzzle s’emboîtaient. 

React a acquis une popularité croissante au cours des deux dernières années. En fait, un certain nombre d’articles sur le marché sont disponibles à l’achat, à l’examen, à la mise en oeuvre, etc. Si vous recherchez des ressources supplémentaires autour de React, n'hésitez pas à les consulter..

Dans le prochain tutoriel, nous utiliserons les connaissances acquises ici pour créer une application React utilisant Redux. Restez à l'écoute d'ici là. Partagez votre opinion dans les commentaires.