Appearance
Créer le reducer dans NgRx
Les reducers en NGRX sont des fonctions pures qui spécifient comment l'état de l'application change en réponse aux actions envoyées au store. Ils prennent l'état actuel et une action comme arguments, puis retournent un nouvel état. Voici comment créer le reducer pour gérer la liste des utilisateurs dans votre application Angular.
1. Rappel, les états
Suite à l'explication des états, nous allons créer la fonction reducer pour gérer les actions.
typescript
import { User } from "./user";
// Interface représentant l'état des utilisateurs
export interface UsersState {
usersList: User[]; // Liste des utilisateurs
loading: boolean; // Indicateur de chargement
}
const usersInitialState: UsersState = {
usersList: [], // Liste initiale vide d'utilisateurs
loading: true // Indicateur de chargement initialisé à true
};
// suite ici
ts
export interface User {
id: number;
name: string;
username?: string;
email: string;
address?: {
street: string;
suite: string;
city: string;
zipcode: string;
geo: {
lat: string;
lng: string;
}
};
phone?: string;
website?: string;
company?: {
name: string;
catchPhrase: string;
bs: string;
};
}
2. Créer le reducer
Nous utilisons createReducer
pour créer le reducer. Nous spécifions comment l'état change en réponse à chaque action en utilisant la fonction on
.
typescript
import { createReducer, on } from "@ngrx/store"
import { usersActions } from "./users.action"
export const usersReducer = createReducer(
usersInitialState,
on(loadUsers, state => ({
...state,
loading: true
})),
on(loadUsersSuccess, (state, { users }) => ({
...state,
usersList: users,
loading: false
})),
on(loadUsersFailure, state => ({
...state,
loading: false
}))
);
- usersInitialState : L'état initial est utilisé comme point de départ. Cela garantit que le reducer commence avec une structure d'état cohérente.
on(loadUsers, ...)
:- Lors de l'action
loadUsers
, nous retournons un nouvel état avecloading
défini surtrue
pour indiquer que les utilisateurs sont en cours de chargement.
- Lors de l'action
on(loadUsersSuccess, ...)
:- Lors de l'action
loadUsersSuccess
, nous mettons à jour l'état avec la nouvelle liste d'utilisateurs et définissonsloading
surfalse
pour indiquer que le chargement est terminé avec succès.
- Lors de l'action
on(loadUsersFailure, ...)
:- Lors de l'action
loadUsersFailure
, nous définissons simplementloading
surfalse
pour indiquer que le chargement a échoué.
- Lors de l'action
Propagation de l'état
À chaque action, nous utilisons l'opérateur de décomposition (...state
) pour créer une copie de l'état actuel, puis nous modifions seulement les propriétés nécessaires. Cela garantit que nous ne mutons pas l'état directement, respectant ainsi le principe d'immuabilité des reducers. [repere 2]
Configuration du reducer
Le reducer doit être intégré dans les configurations du store de votre application Angular. Allez dans app.config.ts
:
typescript
import { ApplicationConfig } from '@angular/core';
import { provideStore } from '@ngrx/store';
import { usersReducer } from './store/users/users.reducer';
export const appConfig: ApplicationConfig = {
providers: [
provideStore({
users: usersReducer
})
]
};
Etre plus rapide avec un Feature
Nous utilisons createFeature
pour regrouper le reducer et l'état initial sous une même fonctionnalité nommée users
.
typescript
import { createFeature } from '@ngrx/store';
// Créer une fonctionnalité pour les utilisateurs
export const usersFeature = createFeature({
name: 'users',
reducer: usersReducer // le reducer plus haut
});
- name: 'users' : Le nom de la fonctionnalité est défini comme
'users'
, ce qui permet d'identifier clairement cette partie de l'état de l'application. - reducer: usersReducer : Le reducer associé à cette fonctionnalité est
usersReducer
, qui gère l'état des utilisateurs en fonction des actions.
L'intérêt est que usersFeature
va vous créer les sélecteurs automatiquement. On aura donc selectUsersList
et selectUsersLoading
qui seront créés automatiquement !
Ajouter des selectors
Si vous souhaitez ajouter d'autres sélecteurs:
ts
export const usersFeature = createFeature({
name: 'users',
reducer: usersReducer,
extraSelectors: ({selectUsers}) => {
return {
selectActiveUsers: createSelector(
selectUsers,
(users) => users.filter(user => user.active)
)
}
}
});
Utilisez extraSelectors
pour ajouter des sélecteurs supplémentaires à la fonctionnalité. Vous pouvez les définir en fonction des sélecteurs existants pour accéder à l'état de manière plus spécifique.
Ensuite, il faut ajouter la fonctionnalité usersFeature
à la configuration du store de votre application Angular. Allez dans app.config.ts
:
typescript
import { ApplicationConfig } from '@angular/core';
import { provideState, provideStore } from '@ngrx/store';
import { usersFeature, usersReducer } from './store/users/users.reducer';
export const appConfig: ApplicationConfig = {
providers: [
provideStore(), // on peut laisser vide si on utilise provideState
provideState(usersFeature)
]
};
Points à retenir
- Les reducers spécifient comment l'état change en réponse aux actions.
- Utilisez
createReducer
eton
pour définir les transformations d'état. - Maintenez l'état immuable en utilisant l'opérateur de décomposition.
- Gérez différentes actions en modifiant uniquement les parties nécessaires de l'état.
Bonnes pratiques
- Gardez les reducers simples et focus sur une seule responsabilité.
- Toujours retourner un nouvel objet d'état au lieu de modifier l'état existant.
- Utilisez des noms d'actions descriptifs pour clarifier leur rôle.
- Combinez plusieurs reducers si l'état de votre application devient complexe.