Redux : Actions, Reducers et Store.
Qu'est-ce que Redux ?
Redux est une bibliothèque JavaScript open-source destinée à la gestion de l'état des applications. Elle est souvent utilisée avec des bibliothèques d'interface utilisateur comme React ou Angular. En centralisant l'état de l'application dans un Store unique, Redux permet de gérer cet état de manière plus prévisible et de simplifier le debug.
Pourquoi utiliser Redux ?
J'utilise Redux pour plusieurs raisons :
Les Actions
Définition et rôle des actions
Les actions sont des objets JavaScript simples qui envoient des informations depuis mon application vers le Store. Elles représentent l'intention de changer quelque chose dans l'état de l'application.
Structure d'une action
Une action contient toujours un type, et éventuellement une payload (charge utile) avec des données supplémentaires. Voici un exemple simple d'action :
const incrementAction = {
type: 'INCREMENT', // Type de l'action, identifie l'intention de l'action
payload: 1 // Données supplémentaires nécessaires pour effectuer l'action
};
Exemples d'actions
Voyons quelques exemples concrets d'actions que je pourrais utiliser dans une application de panier d'achats :
// Action pour ajouter un article à un panier
const addItemAction = {
type: 'ADD_ITEM',
payload: {
id: 1,
name: 'Apple',
quantity: 3
}
};
// Action pour supprimer un article du panier
const removeItemAction = {
type: 'REMOVE_ITEM',
payload: {
id: 1
}
};
Les Reducers
Définition et rôle des reducers
Les reducers sont des fonctions pures qui prennent l'état actuel et une action comme arguments, et retournent un nouvel état. Ils déterminent comment l'état de l'application doit changer en réponse à une action envoyée au Store.
Comment fonctionnent les reducers ?
Les reducers analysent l'action reçue et mettent à jour l'état en conséquence. Voici un exemple simple de reducer pour un compteur :
const initialState = {
count: 0 // État initial du compteur
};
function counterReducer(state = initialState, action) {
switch (action.type) {
case 'INCREMENT':
return {
...state, // Copie l'état actuel
count: state.count + action.payload // Met à jour la valeur de 'count'
};
case 'DECREMENT':
return {
...state,
count: state.count - action.payload
};
default:
return state; // Retourne l'état inchangé pour les actions non reconnues
}
}
Exemples de reducers
Voici un autre exemple, cette fois pour un panier d'achats :
const cartInitialState = {
items: [] // État initial du panier, une liste vide d'articles
};
function cartReducer(state = cartInitialState, action) {
switch (action.type) {
case 'ADD_ITEM':
return {
...state,
items: [...state.items, action.payload] // Ajoute le nouvel article à la liste
};
case 'REMOVE_ITEM':
return {
...state,
items: state.items.filter(item => item.id !== action.payload.id) // Supprime l'article avec l'ID correspondant
};
default:
return state;
}
}
Le Store
Définition et rôle du store
Le Store est un objet qui contient l'état de l'application. Il est créé en utilisant la fonction createStore de Redux. Le Store permet de lire l'état via la méthode getState(), d'envoyer des actions via dispatch(action) et de s'abonner aux changements d'état via subscribe(listener).
Recommandé par LinkedIn
Création du store
Voici comment je crée un Store en utilisant Redux :
import { createStore } from 'redux'; // Importation de la fonction createStore depuis Redux
import rootReducer from './reducers'; // Importation des reducers combinés
const store = createStore(rootReducer); // Création du store en passant les reducers
Copy code
import { createStore } from 'redux'; // Importation de la fonction createStore depuis Redux import rootReducer from './reducers'; // Importation des reducers combinés const store = createStore(rootReducer); // Création du store en passant les reducers
Intégration du store dans une application React
Pour intégrer le Store dans une application React, j'utilise le composant Provider de la bibliothèque react-redux :
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'; // Importation du composant Provider
import App from './App'; // Importation du composant principal de l'application
import store from './store'; // Importation du store
ReactDOM.render(
<Provider store={store}>
<App /> {/* Le composant App a maintenant accès au store Redux */}
</Provider>,
document.getElementById('root')
);
Flux de Données avec Redux
Redux suit un flux de données unidirectionnel. Voici comment les différentes parties interagissent :
Exemple Pratique
Pour mieux comprendre, mettons en place un petit projet Redux.
Création d'actions
// actions.js
export const addItem = item => ({
type: 'ADD_ITEM', // Type de l'action pour ajouter un article
payload: item // Données de l'article à ajouter
});
export const removeItem = id => ({
type: 'REMOVE_ITEM', // Type de l'action pour supprimer un article
payload: { id } // ID de l'article à supprimer
});
Création de reducers
// reducers.js
const initialState = {
items: [] // État initial, une liste vide d'articles
};
const cartReducer = (state = initialState, action) => {
switch (action.type) {
case 'ADD_ITEM':
return {
...state,
items: [...state.items, action.payload] // Ajoute l'article à la liste
};
case 'REMOVE_ITEM':
return {
...state,
items: state.items.filter(item => item.id !== action.payload.id) // Filtre l'article à supprimer
};
default:
return state; // Retourne l'état inchangé pour les actions non reconnues
}
};
export default cartReducer;
Création du store
// store.js
import { createStore } from 'redux'; // Importation de la fonction createStore
import cartReducer from './reducers'; // Importation du reducer
const store = createStore(cartReducer); // Création du store avec le reducer
export default store;
Intégration dans une application React
// App.js
import React from 'react';
import { useDispatch, useSelector } from 'react-redux'; // Importation des hooks useDispatch et useSelector
import { addItem, removeItem } from './actions'; // Importation des actions
const App = () => {
const dispatch = useDispatch(); // Hook pour envoyer des actions
const items = useSelector(state => state.items); // Hook pour accéder à l'état du store
const handleAddItem = () => {
const newItem = { id: items.length + 1, name: `Item ${items.length + 1}` };
dispatch(addItem(newItem)); // Envoie l'action pour ajouter un article
};
const handleRemoveItem = id => {
dispatch(removeItem(id)); // Envoie l'action pour supprimer un article
};
return (
<div>
<h1>Shopping Cart</h1>
<button onClick={handleAddItem}>Add Item</button>
<ul>
{items.map(item => (
<li key={item.id}>
{item.name} <button onClick={() => handleRemoveItem(item.id)}>Remove</button>
</li>
))}
</ul>
</div>
);
};
export default App;
Glossaire des Termes Techniques
Conclusion
Redux est un outil puissant pour la gestion d'état dans les applications JavaScript modernes. En comprenant les concepts fondamentaux des Actions, Reducers et du Store, vous serez en mesure de construire des applications plus maintenables et prévisibles. Pour aller plus loin, explorez les middleware comme Redux Thunk ou Redux Saga, et pratiquez en intégrant Redux dans vos projets.