Redux

Dans le développement front-end moderne, la gestion de l’état d’une application est un défi majeur. Lorsqu’une application React grandit, l’échange de données entre les composants devient complexe. C’est ici que Redux intervient.

Redux est une bibliothèque open-source permettant de centraliser et gérer l’état global d’une application JavaScript. Développée par Dan Abramov et Andrew Clark en 2015, elle repose sur une architecture prévisible et facilite la gestion des mises à jour de l’interface utilisateur.

Bien que souvent associée à React, Redux peut être utilisé avec n’importe quelle bibliothèque ou framework JavaScript comme Vue.js ou Angular. Son objectif est de garantir une gestion efficace, prévisible et scalable des données de l’application.

Pourquoi utiliser Redux ?

Dans une application React traditionnelle, l’état est souvent stocké dans les composants locaux via useState(). Toutefois, lorsque plusieurs composants doivent partager un même état, cela engendre une prop drilling, c’est-à-dire une transmission excessive des props à travers plusieurs niveaux.

Redux résout ce problème en centralisant l’état de l’application dans un store global, permettant à tous les composants d’y accéder sans passer par des props.

Avantages de Redux :

  • Centralisation de l’état : tous les composants accèdent aux mêmes données sans passer par des props intermédiaires.
  • Débogage simplifié : grâce aux outils comme Redux DevTools, il est possible d’analyser chaque modification de l’état.
  • Architecture prévisible : les mises à jour de l’état suivent un flux strict et immuable, garantissant une plus grande stabilité.
  • Amélioration des performances : évite les rendus inutiles en optimisant la mise à jour des composants.

Les principes fondamentaux de Redux

Redux repose sur trois principes clés :

1. Un seul store global

Contrairement à React où chaque composant peut avoir son propre état (useState), Redux utilise un seul store qui contient tout l’état de l’application.

Exemple d’un état global Redux :

const initialState = {
  user: { name: "Alice", isLoggedIn: true },
  cart: { items: [], total: 0 }
};

2. L’état est immuable et ne peut être modifié directement

Dans Redux, l’état ne peut pas être modifié directement. Au lieu de cela, il est mis à jour par des actions qui sont traitées par des reducers.

3. Les modifications se font via des actions et des reducers

Les mises à jour du store passent obligatoirement par des actions (des objets décrivant l’intention de modification) et des reducers (des fonctions qui appliquent ces modifications).

Comment fonctionne Redux ?

1. Le Store : un état centralisé

Le store est un objet unique qui contient l’ensemble des données de l’application. Il est créé via createStore() et doit être accessible à tous les composants.

2. Les Actions : des objets décrivant les intentions de modification

Une action est un simple objet JavaScript qui décrit ce qui doit être fait. Elle possède un type (une chaîne de caractères) et parfois un payload (des données associées).

Exemple d’action :

const addItemToCart = (item) => {
  return {
    type: "ADD_ITEM",
    payload: item
  };
};

3. Les Reducers : des fonctions pures qui appliquent les modifications

Un reducer est une fonction pure qui prend l’état actuel et une action, et retourne un nouvel état.

Exemple de reducer pour un panier d’achats :

const cartReducer = (state = { items: [], total: 0 }, action) => {
  switch (action.type) {
    case "ADD_ITEM":
      return {
        ...state,
        items: [...state.items, action.payload],
        total: state.total + action.payload.price
      };
    default:
      return state;
  }
};

4. Le Dispatch : envoyer une action pour modifier l’état

Pour modifier l’état, une action doit être envoyée via la méthode dispatch().

Exemple :

store.dispatch(addItemToCart({ name: "Laptop", price: 1200 }));

Intégration de Redux avec React

Redux s’intègre facilement avec React grâce à la bibliothèque react-redux, qui permet de connecter les composants au store.

1. Installation de Redux et React-Redux

npm install redux react-redux

2. Création du store Redux

import { createStore } from "redux";
import { Provider } from "react-redux";
import cartReducer from "./reducers/cartReducer";

const store = createStore(cartReducer);

function App() {
  return (
    <Provider store={store}>
      <ShoppingCart />
    </Provider>
  );
}

3. Connexion d’un composant au store

Un composant peut accéder à l’état global avec useSelector() et envoyer des actions avec useDispatch().

import { useSelector, useDispatch } from "react-redux";

function ShoppingCart() {
  const cart = useSelector((state) => state);
  const dispatch = useDispatch();

  return (
    <div>
      <h2>Panier</h2>
      <ul>
        {cart.items.map((item, index) => (
          <li key={index}>{item.name} - {item.price}€</li>
        ))}
      </ul>
      <button onClick={() => dispatch({ type: "ADD_ITEM", payload: { name: "Smartphone", price: 800 } })}>
        Ajouter un smartphone
      </button>
    </div>
  );
}

Redux vs Context API : Que choisir ?

Depuis React 16.3, la Context API permet également de partager un état global entre composants sans passer par Redux.
Alors, quel outil choisir ?

CritèreReduxContext API
ComplexitéÉlevée (configuration plus lourde)Faible (intégré à React)
ScalabilitéAdapté aux grandes applicationsLimité pour de gros projets
PerformanceOptimisé avec useSelector() et memoizationMoins performant sur des gros états
DébogageOutils comme Redux DevToolsMoins de contrôle

Si l’application est petite ou moyenne, Context API peut suffire.
Pour une application complexe avec beaucoup d’état partagé, Redux reste une solution robuste.

Alternatives et évolutions de Redux

Bien que Redux soit largement adopté, plusieurs alternatives émergent :

  • Recoil : plus simple et natif pour React.
  • Zustand : état global sans complexité.
  • Jotai : approche plus fine et réactive.

Redux évolue également avec Redux Toolkit, une version simplifiée qui réduit la configuration et le boilerplate.

Redux est une solution puissante pour gérer l’état global des applications front-end complexes. En imposant une structure stricte, il facilite la maintenance et le débogage des applications à grande échelle.

Toutefois, avec l’évolution des outils comme React Context API, Recoil et Redux Toolkit, son adoption dépend du besoin réel du projet. Pour les petites applications, une approche plus légère peut être préférable.