Les reducers dans Redux : Gérer la mise à jour de l'état
Le rôle central des reducers
Dans une application, l'état représente les données qui font fonctionner l'interface utilisateur. Les reducers sont des fonctions qui indiquent comment cet état est mis à jour en réponse à des actions.
Comprendre le fonctionnement d'un reducer
Un reducer est une fonction qui prend deux arguments :
- L'état actuel (`state`) : Les informations que le reducer gère.
- L'action (`action`) : Un objet qui décrit ce qui s'est passé.
Le reducer examine le type de l'action et retourne un nouvel état basé sur cette action. Il est important de ne pas modifier l'état actuel directement, mais de créer une nouvelle copie avec les changements.
function counterReducer(state = { value: 0 }, action) {
switch (action.type) {
case 'INCREMENT':
return { ...state, value: state.value + 1 };
case 'DECREMENT':
return { ...state, value: state.value - 1 };
default:
return state;
}
}
Dans cet exemple, `counterReducer` gère un compteur. Selon l'action, il augmente ou diminue la valeur. Si l'action n'est pas reconnue, il renvoie l'état sans changement.
Principes fondamentaux des reducers
- Immutabilité : Les reducers doivent toujours retourner un nouvel objet d'état, garantissant ainsi la prévisibilité et facilitant le suivi des changements.
- Fonctions pures : Les reducers doivent être des fonctions déterministes, sans effets secondaires, produisant le même résultat pour les mêmes entrées.
- Responsabilité unique : Chaque reducer doit se concentrer sur la gestion d'une section spécifique de l'état global de l'application.
- Dépendance du type d'action : La logique de mise à jour de l'état est conditionnée par le type de l'action reçue.
- Tests unitaires : L'écriture de tests pour les reducers est essentielle pour valider leur comportement et prévenir les régressions.
Redux Toolkit et la simplification des reducers
Redux Toolkit est une librairie qui facilite l'utilisation de Redux. Elle propose notamment l'outil `createSlice` qui simplifie l'écriture des reducers.
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: (state) => { state.value += 1; },
decrement: (state) => { state.value -= 1; }
}
});
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
`createSlice` permet de définir le nom de la slice, l'état initial et les reducers dans un seul objet. Il utilise Immer en interne, ce qui nous permet d'écrire le code comme si on modifiait l'état directement. Redux Toolkit se charge ensuite de gérer l'immutabilité correctement.
L'utilisation de `createSlice` simplifie la syntaxe et réduit la quantité de code nécessaire pour gérer l'état.
Où utilise-t-on les reducers ?
Les reducers sont utilisés pour gérer différents aspects de l'état de l'application, comme :
- Les données des utilisateurs.
- L'état des formulaires.
- Les listes d'éléments.
- Les préférences de l'interface.
Chaque slice est responsable de la gestion d'une section de l'état global. Les reducers, qui sont définis à l'intérieur de chaque slice, sont les fonctions qui effectuent les modifications de l'état pour cette section.
Conclusion
En résumé, les reducers sont les fonctions qui décident comment l'état de votre application Redux change. Que vous utilisiez des reducers simples ou que vous profitiez de la simplification offerte par Redux Toolkit et `createSlice`, bien comprendre leur fonctionnement est une étape clé pour construire des applications avec un flux de données clair et facile à maintenir.