Comment bien gérer la cohérence des données dans vos applications Web ?
Gérer l’état de notre application Web dépend de nombreux facteurs : expérience des devs, frameworks et librairies utilisées, architecture mise en place… Il convient donc d’uniformiser les pratiques afin de répondre au mieux à cette problématique que tous les développeurs rencontrent à chaque nouveau projet.
Dans le cadre d’un grand projet de transformation chez l’un de nos clients, spécialisé dans le transport transfrontalier de personnes et de marchandises, nous avons migré certaines applications de AngularJS vers Angular. Nous ne nous sommes pas juste contentés de reprendre l’ancien code source pour l’adapter au nouveau framework. Nous avons également revu la manière de gérer les données de notre application en intégrant la librairie NgRx, qui est l’association Angular + Redux + RxJS.
Gérer ce qu’on appelle “l’état” de notre application est ce que nous faisons à chaque fois que nous développons une application Web: nous récupérons des données depuis une API, nous les mettons à jour, nous les modifions…
Cette gestion va fortement dépendre des pratiques et des habitudes des développeurs, en fonction de leur expérience, des frameworks et des librairies utilisées, des architectures mises en place… Il y a donc N façons de faire.
La librairie React a popularisé le concept de pattern state, avec l’introduction de Redux, qui apporte un cadre où la gestion de cet état va se faire à l’aide de classes/fonctions faiblement couplées et prédictibles. NgRx est donc l’adaptation de Redux pour Angular.
1.
Le pattern state
Ce pattern nous permet de gérer l’état de notre application, c’est-à-dire toutes les données de notre application à un instant T.
Il fixe un cadre précis (un workflow pour être plus précis) afin de gérer le rafraîchissement des données et de limiter les effets de bord.
3 principes importants :
⦁ Les données de l’application (state) sont contenues dans le store, qui devient la seule source de vérité.
⦁ Le state est global, et donc accessible à n’importe quel composant via le store.
⦁ Le state est en lecture seule. Un composant ne peut donc pas le modifier directement.
Cet état (state) est stocké dans un objet Javascript appelé le store.
2.
Modifier le state
Tout changement du state n’est possible que par l’intermédiaire d’actions et de reducers.
⦁ Une action peut-être déclenchée dans le but de provoquer une mise à jour du state. Concrètement, une action est caractérisée par un nom (et un payload si l’on veut transmettre des paramètres).
⦁ Un reducer est une fonction pure : elle retourne le même résultat pour les mêmes paramètres d’entrée et n’a pas d’effet de bord. On peut donc commencer à parler de prédictibilité.
Tous ces éléments sont liés par un mécanisme de dispatcher et ne sont donc pas fortement couplés.
3.
Gérer le code qui ne relève pas du state
Les side effects (ou « effets de bords ») sont des fonctions non pures qui vont être aussi déclenchées par des actions.
Elles permettent de gérer tout ce qui ne relève pas du state (appels HTTP, accès au localStorage, ouverture d’une popin’ etc.).
4.
Débuggez plus facilement votre application
Grâce aussi à Redux DevTools, il devient plus aisé d’observer l’impact d’une action sur l’état de notre application et de le débugger.
Redux DevTools est une extension pour votre navigateur qui permet d’observer et de loguer les actions jouées et ce, dans le but de comprendre le fonctionnement de l’application mais aussi pour la debugger.
Redux DevTools va lister chaque action exécutée dans le temps et montrer son impact (ou plutôt celui du reducer) sur le state.
Redux DevTools ne s’arrête pas là. Il permet également de rejouer une ou plusieurs action(s) ou même la totalité pour voir les impacts sur le state au fur et à mesure.
Il est également possible d’importer ou exporter un state (au format .json) pour l’exploiter et même rejouer un scénario complet.