Retour d'expérience : le système de paiement chez Club Med
Gauthier Cornette, Développeur, et Arthur Morel, Head of Digital Indirect Sales, reviennent sur les systèmes de paiement de l’application CMTA.
Lorsqu’on réalise un projet React d’envergure et avec de la gestion de données (pour des formulaires par exemple), on peut vite se poser la question : comment gérer tous nos états et leurs adhérences?
Redux peut être une bonne solution.
Redux est une librarie React qui permet de centraliser et d’uniformiser la gestion des états d’une application. À la différence de useContext et useReducer, Redux est conçu pour manager l’ensemble des états de l’application.
Ce gif montre comment fonctionne le stockage. Nous allons nous pencher sur les détails plus tard.
Pour être sûr de prendre la bonne décision, il faut se poser les questions suivantes :
Plus vous aurez de composants ayant besoin de récupérer des états et de les modifier, plus il sera utile d’ajouter Redux à votre projet.
Reprenons ce gif et voyons ce qui se passe plus en détail.
Tout d'abord, l'état est initialisé dans la partie “Store” (l’endroit où sont stockés nos états). Une fois fait, ces états seront accessibles dans toute l'application.
Ici, l'interface utilisateur est notre application construite avec des composants React. Dans cet exemple, l'interface utilisateur se compose simplement de deux boutons : l'un est utilisé pour déposer 10$, l'autre est utilisé pour retirer 10$.
Pour correspondre aux états initialisés dans le store, on utilise useSelector dans notre fichier React pour interroger les données et ainsi les afficher.
L'utilisateur clique sur "Déposer 10 $". Voyons ce qui se passe ensuite avec la partie dispatch.
L'événement est lancé et nous devons utiliser un dispatch dans notre "onClick" pour créer une action.
Par exemple :
<button ... onClick={() => dispatch(ourActions.deposit_10()} ...> Deposit $10</button>
Le dispatch est un hook utilisé pour faire le lien entre notre interface utilisateur et nos actions, qui serviront celles-ci à communiquer aux reducers qu'il y a eu un changement.
Le fichier contenant les actions ressemble à une liste de toutes les actions que vous pouvez faire dans l'application.
Ces actions sont des fonctions qui renvoient des objets. Ces objets contiennent le type d'action à prendre et, si nécessaire, un payload (charge utile en français) qui sera utilisé pour modifier nos données.
const deposit_10 = () => { type: "DEPOSIT_10" payload: {}}const withdraw_10 = () => { type: "WITHDRAW_10" payload: {}}
Ici, le payload est vide car notre information est dans le type des actions. Mais si nous souhaitons faire des types différents de transactions (comme par exemple retirer 5$) nous sommes :
- Soit obligé de faire une nouvelle action withdraw_5
- Soit nous pouvons faire une action plus globale et nous n'aurons plus qu'un type "TRANSACTION".
Cette action ressemblerait à ceci :
const transaction = (value) => { type: "TRANSACTION" payload: { value }}
Ce type d’actions est, de ce fait, plus général et plus optimal à utiliser, que de diviser un même type d’action en plusieurs actions. L’exemple ci-dessus est assez évident, mais en pratique, il arrive parfois de diviser ses actions en plusieurs actions sans que ce soit nécessaire.
En général, on essaie d’avoir une action par état.
Les reducers sont des fonctions Javascript qui connaissent l'état précédent de nos données et les renvoient avec leurs nouveaux états mis à jour.
const initialBankAccountState = { amountOfMoney: 100}const bankAccountReducer = (state = initialBankAccountState, action) => { switch (action.type) { case "DEPOSIT_10": return { ...state, amountOfMonay: state.amountOfMoney + 10 } case "WITHDRAW_10": const amount = state.amountOfMoney; return { ...state, amountOfMonay: amount >= 10 ? amount - 10 : amount } // we can't withdraw money if the amount on our bank account is // under $10 default: return state }}
Notez que chaque reducer doit gérer le cas default où, si aucun des cas du switch ne correspond à l'action passée, alors le reducer doit renvoyer l'état tel quel ou effectuer une logique requise dessus avant de renvoyer nos états.
Pour suivre notre autre exemple plus optimal, notre switch case se résumerait comme ceci :
case "TRANSACTION": return { const newAmount = state.amountOfMoney + action.payload ...state, amountOfMonay: newAmount > 0 ? newAmount : state.amountOfMoney } // we can't withdraw money if the amount on our bank account is // under what we want to withdraw
Lorsque vous voulez débuguer Redux, vous pouvez utiliser Redux-devtool. C’est un outil qui facilite la trace de quand, où, pourquoi et comment l'état de votre application a changé.
Redux-toolkit permet d’avoir des suggestions sur les pratiques de Redux, le simplifie et évite les erreur les plus courantes pour faciliter l’écriture d’application avec Redux.
Il permet au store de communiquer de manière asynchrone avec des ressources extérieures à ce store, ce qui inclut l'accès au stockage local, les requêtes HTTP et l'exécution de services d'entrée et de sortie gérés efficacement.
Cette extension permet de suivre les états et les actions du payload.
Redux est un plus à vos applications React, ce qui peut être vraiment utile dans un projet. Pensez-y lorsque vous commencez un nouveau projet et facilitez votre gestion d'états !
Nous croyons en un nouveau modèle de consulting où l’excellence commence par l’écoute, le partage et une vraie vision