Introduction
Last updated
Was this helpful?
Last updated
Was this helpful?
Dans cet article, nous allons voir comment utiliser le pattern Redux dans une application Angular via NGRX. Ce dernier proposant une conception du développement d'application autour d'actions utilisateur et serveur.
Le but étant de supprimer les différentes mutations de données des composants et services Angular pour les centraliser dans un objet global, qui serait mutable uniquement par des actions typées.
Pour le développement sur Angular, Visual studio code est fortement recommandé. Vous devrez aussi installer Angular sur votre machine avec la commande npm i -g @angular/cli.
Intérêt de NGRX
Le 1er avantage est le modèle unidirectionnel avec lequel nous travaillerons, ce qui n'est pas le cas du standard MVC qui est bidirectionnel.
Le 2ème avantage est "l'historisation". Comme tous les changements transitent par le store, chaque update/modification est loggé. Grâce à cela, nous pouvons remonter dans l'historique et trouver quelle mutation a créer un bug : c'est une sorte de state machine.
Comme Angular peut être utilisé avec Typescript , NRGX profite également du typage qui va verrouiller nos actions et ainsi lever plus tôt les erreurs en cours de développement.
C’est un pattern né de Flux, une architecture créée par Facebook. Il apporte un workflow de données unidirectionnelles grâce à un dispatcher, qui recueil des actions distribuées par le serveur ou par l’utilisateur. Il conserve la nouvelle instance d’une donnée dans un ou plusieurs stores qui mettent à jour la vue.
L'architecture de Flux ci-dessus peut contenir plusieurs structures de données indépendantes appelées Store. Chaque action passe par le dispatcher, qui la transmet au store ciblé par l'action.
Redux est une version moins complexe de Flux. Il se distingue en plusieurs points :
Un store, donc une source de données ;
Des états immuables / immutables
Pas de dispatcher.
Flux
Redux
Les stores contiennent les états et leurs logiques de mutations
Le store et leurs logiques de mutation sont séparés
Plusieurs stores
Un seul store
Stores indépendants
Store unique avec reducers
Dispatcher
Pas de dispatcher
Etats mutables
Etats immuables
Le store est une fonction qui contient l'état des reducers, un getter, une fonction de dispatch et des subscribers.
Voici un exemple de store from scratch simplifié :
Exemple
Comment faire une instance du store :
Le root reducer est un simple objet qui a pour propriété des fonctions. Celles-ci représentent l'ensemble des mutations de l'application.
Exemple
Chaques fonctions reducer a pour argument son état et une action.
Exemple
Les reducers ne fonctionnent qu'avec des fonctions pures. Ils ne doivent jamais modifier directement l'état, mais en renvoyer un nouveau à partir de celui-ci.
Les reducers encapsulent les différentes logiques de mutation, et le store contient le résultat de chaque reducer comme deux objets miroirs synchronisés à chaque action.
Les actions sont des objets. Elles contiennent au minimum une propriété type.
Cette propriété donne la possibilité au reducer de savoir quelle mutation appliquer sur l'état actuel. Le nommage du type doit être explicite afin de garder une bonne traçabilité lors d'un changement. Une meilleure pratique consiste à utiliser des constantes qui permettent d'écrire des types d'actions plus lisibles.
Comme il s'agit d'un objet, on peut lui rajouter autant de propriétés que l'on souhaite :
Il existe une manière différente et préférable de réaliser une action, celle d'utiliser une classe qui permettra de générer notre objet d'action.
Elle s'utilise à la place de l'objet.
L'action creator permet également de mieux utiliser le typage pour les valeurs optionnelles. Maintenant que nous avons la structure de l'action, nous allons voir comment l'injecter dans le store. Grâce à la méthode dispatch, on va pouvoir mettre à jour l'état du Counter avec l'action passée en paramètre.
Grâce à la programmation fonctionnelle, le dispatcher est complètement retiré du schéma qui rend le développement plus simple.