Le blog de la Wild Code School - Wild Code School

Guide Complet : utiliser Redux avec React

Rédigé par Julien Richard | 17/06/2024

À mesure que les applications deviennent plus complexes, les développeurs avancés cherchent à mettre en place des architectures en couches pour mieux structurer leur code. Une telle approche permet non seulement de gérer la complexité, mais aussi de rendre l'application plus maintenable et évolutive. Cette évolution dans notre organisation de code doit être prise en compte de manière globale. 

Pourquoi utiliser un système de gestion d'état global ?

Gestion de la complexité

  • Un état de donnée partagé évite la cascade de “props” entre nos composants.

Une seule source de vérité

  • Dissociation de nos fichiers gérant nos données de nos fichiers gérant l’affichage.

Portabilité et réutilisation

  • Utiliser Redux permet de mieux gérer la couche de données de notre application en la rendant plus facilement transférable vers une autre bibliothèque ou framework. Par exemple, cela facilite la mise en place d'une application mobile avec React Native, car le code de gestion de nos données n'est pas directement lié à React.

Mise en place d’un projet React avec Redux

Redux est une bibliothèque JavaScript permettant de gérer l’état de nos données dans notre application React. Elle est aujourd’hui l’une des plus utilisées dans les applications Front End et est compatible avec différentes bibliothèques.

La gestion de l’état de nos données avec Redux s’organise en trois parties distinctes :

  1. Le Store : un conteneur centralisé pour l'état global de votre application. Il permet de stocker l'ensemble des données de l'application. Le store est unique et constitue la source unique de vérité, facilitant ainsi la gestion et le suivi de l'état de l'application de manière prévisible et structurée. (cf doc)
  2. Le Reducer : une fonction qui prend l'état actuel et une action comme arguments, et retourne un nouvel état mis à jour en fonction de l'action. Les reducers spécifient comment l'état de l'application doit changer en réponse à une action envoyée au store. (cf doc)
  3. Les Actions : des objets JavaScript qui décrivent un événement ou une intention de changement dans l'application. (cf doc)

Implémenter Redux dans React

Pour ce faire, nous allons créer une petite application de gestion de liste de courses. Nous pouvons la résumer en U.S :

  • En tant qu’utilisateur, je peux voir la liste des produits.
  • En tant qu’utilisateur, je peux modifier la quantité de produits.
  • En tant qu’utilisateur, je peux modifier le statut d’un produit.
  • En tant qu’utilisateur, je peux ajouter un produit.

 

 

Pour commencer, retrouvez le code de base du projet avec les composants sur ce repo :

1) Quelles dépendances installer pour React ?

Pour implémenter Redux dans notre application React, vous aurez besoin de 2 packages : react-redux et redux toolkit (cf Documentation officielle ).


2)  Comment configurer correctement mon ensemble ?

Actions

Dans un premier temps, nous allons créer une première action. (Pour rappel, une action est un événement entraînant un changement dans nos données). Par exemple, pour répondre à l’US de la mise à jour de la quantité, nommons notre action “quantity”.

Dans notre dossier Redux, ouvrons notre fichier action.js. À l’intérieur de ce fichier, nous allons lister nos actions.

 

Reducer

Une fois notre action mise en place, nous allons mettre en place la description (ce que doit faire notre code quand l’action est demandée) dans notre reducer (deuxième fichier nécessaire).

À l’intérieur de ce fichier, nous allons importer nos actions (une seule pour le moment) et créer, via un objet builder de la bibliothèque Redux, une liste d’actions (On peut voir ce builder comme un équivalent de switch).

La méthode createReducer accepte deux arguments :

  • Notre store initial (il se situe actuellement dans notre fichier ./assets/shop.js). On va l’importer dans notre fichier reducer.
  • Une fonction mettant en corrélation nos actions avec la modification de l’état de nos données voulue.

Dans ce code, la logique pour mettre à jour la quantité est déjà mise en place dans la méthode addCase.

Store

Dernière étape, la création de notre store partageable entre nos composants. Ouvrons notre fichier store.js et ajoutons le code suivant :

Nous avons un code tout simple, mais il est possible d’envisager plusieurs logiques métiers, et donc plusieurs reducers, implémentant de nombreuses actions. Le fichier du store permet de centraliser l’ensemble de nos états de données.

Configuration

Pour rendre les données accessibles à l’ensemble de nos pages et composants de notre application, nous allons encadrer notre <App /> avec son <Provider /> (son fournisseur de données).

Félicitations 🚀 🚀 🚀

3. Comment consommer les données de mon store ? (US n°1)

Notre système est mis en place. Vérifions-le.

Dans le fichier ToDos.jsx, importons le hook useSelector de la bibliothèque react-redux pour récupérer notre store. Supprimons notre import de données (shoppingList). Et récupérons-le maintenant depuis notre store.

Lançons notre projet avec npm run dev. Notre liste d’articles doit toujours s’afficher. Notre donnée est bien centralisée.

De la même manière, nous pouvons maintenant modifier notre Header.jsx pour afficher le nombre d’éléments actuellement à acheter. Importez le hook useSelector et gérez la logique de filtre dans votre composant.

Bravo ! Notre application est pleinement prête.

4. Comment consommer nos actions (événements) modifiant notre état de données ? (US n°2)

La liaison entre nos actions et l’état de notre donnée se situe dans notre fichier reducer.js. C’est notre intermédiaire, permettant une bonne séparation des préoccupations.

Regardons attentivement le code. Nous avons déjà mis en place la logique. Dans notre builder, nous ajoutons un cas applicatif (addCase). Cette méthode nécessite deux arguments :

  • L’objet de notre action (ici quantity).
  • Une fonction (recevant deux paramètres, l’objet du store actuel et les données envoyées au moment de l’appel à l’action, par défaut nommée payload). Dans cette fonction, nous allons pouvoir implémenter directement notre logique de mutation de la donnée.

Et maintenant, implémentons la logique dans notre composant.

Dans le fichier ToDos.jsx, il faut :

  • Modifier nos imports en ajoutant dispatch de la bibliothèque react-redux et importer également notre action (quantity).
  • Activer le hook de dispatch dans notre composant.
  • Ajouter un écouteur d'événement onChange sur notre input cible. Dans son appel à fonction, on va distribuer l’action voulue en n’oubliant pas les arguments consignés dans un objet.

 

5. On se lance dans notre US n°3 : modifier le statut.

À vous de jouer :

  • Commencez par créer une nouvelle action.
  • Importez cette action dans le reducer et ajoutez un cas d’usage (addCase) et intégrez-y la logique dans la fonction de rappel (callback).
  • Dans votre composant ToDos.jsx, importez l’action et ajoutez la logique dans votre select.

Voici le code final :

6. Dernière ligne droite, US n°4 : l’ajout d’un produit.

Maintenant que notre système est mis en place, on réalise que les étapes sont toujours les mêmes :

  • Mettre en place une action.
  • Décrire le comportement de l’action dans notre reducer.
  • Consommer l’action via le hook de dispatch dans notre composant.

À vous de jouer.

Retrouvez le code final de l’application ici

 

Conclusion

On réalise rapidement que le degré de complexité pour la mise en place de Redux dans React va vite être compensé dans notre quotidien par le gain de temps en ajout de fonctionnalités, maintenabilité et prévision du comportement de notre application.

Alternatives à Redux

Context API et useReducer

Pour des applications moins complexes, la combinaison de Context API et useReducer peut être une alternative légère à Redux. Context API permet de passer des données à travers l'arborescence des composants sans avoir à passer manuellement des props à chaque niveau. useReducer, quant à lui, est un hook qui permet de gérer l'état local du composant de manière similaire à Redux, en utilisant une fonction reducer. (Notion abordée dans nos Bootcamps 5 mois)

Zustand

Zustand est une autre bibliothèque légère pour la gestion d'état dans React. Elle offre une API simple et intuitive et peut être une excellente alternative pour des projets de petite à moyenne taille.

 

En conclusion, la gestion de l'état global dans une application React peut être réalisée de différentes manières selon la complexité du projet et les besoins spécifiques. Redux, Context API avec useReducer, et Zustand sont toutes des solutions viables offrant divers niveaux de complexité et de fonctionnalités.