Passer à l'article

Aide-Mémoire Redux Toolkit

Posted on:3 décembre 2023 at 11:18

Redux permet de gérer l’état global d’une application React. Cet article me sert de mémo / référence pour la mise en place de Redux Toolkit sur un projet React.

Rappel : les principes de Redux

Redux est une librairie qui permet de gérer l’état global d’une application React. Elle repose sur 3 principes :

Elements de base de Redux :

Comment mettre en place Redux Toolkit ?

1. Installer Redux Toolkit

npm install @reduxjs/toolkit react-redux

2. Créer un store

Créer un fichier store.js traditionnellement dans un dossier store. Ce fichier contient la configuration du store Redux.

import { configureStore } from "@reduxjs/toolkit";

export default configureStore({
  reducer: {},
});

3. Fournir le store à l’application

A la racine de l’application, fournir le store à l’application avec le composant Provider de react-redux.

import { Provider } from "react-redux";
import store from "./store/store"; // Le store créé précédemment

ReactDOM.createRoot(document.getElementById("root")).render(
  <Provider store={store}>
    <App />
  </Provider>
);

4. Créer une “slice”

Une slice est un ensemble de fonctions qui permettent de modifier l’état de l’application. Une slice contient. Dans un fichier ./features/counter/counterSlice.js :

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  value: 0,
};

export const counterSlice = createSlice({
  name: "counter",
  initialState,
  reducers: {
    increment: state => {
      // Redux Toolkit allows us to write "mutating" logic in reducers. It
      // doesn't actually mutate the state because it uses the Immer library,
      // which detects changes to a "draft state" and produces a brand new
      // immutable state based off those changes
      state.value += 1;
    },
    decrement: state => {
      state.value -= 1;
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload;
    },
  },
});

// Action creators are generated for each case reducer function
export const { increment, decrement, incrementByAmount } = counterSlice.actions;

export default counterSlice.reducer;

5. Ajouter la slice au store

Dans le fichier store.js :

import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "../features/counter/counterSlice";

export const store = configureStore({
  reducer: {
    counter: counterReducer,
  },
});

Utiliser le store dans un composant

1. Récupérer les données du store

Pour récupérer les données du store dans un composant, utiliser le hook useSelector de react-redux.

import { useSelector } from "react-redux";

const Counter = () => {
  const count = useSelector(state => state.counter.value);

  return (
    <div>
      <span>{count}</span>
    </div>
  );
};

2. Modifier les données du store

Pour modifier les données du store dans un composant, utiliser le hook useDispatch de react-redux et les actions généré depuis la slice.

import { useDispatch } from "react-redux";
import { increment, decrement } from "./counterSlice";

const Counter = () => {
  const dispatch = useDispatch();

  return (
    <div>
      <button onClick={() => dispatch(increment())}>+</button>
      <button onClick={() => dispatch(decrement())}>-</button>
      <button onClick={() => dispatch(incrementByAmount(5))}>+5</button>
    </div>
  );
};

Middleware

Un middleware est une fonction qui permet de modifier le comportement de Redux. Il est appelé à chaque fois qu’une action est envoyée au store. Il peut être utilisé pour logger les actions, pour gérer des actions asynchrones, etc.

1. Créer un middleware

Créer un fichier ./store/middleware.js :

const monMiddleware = store => next => action => {
  // Votre logique de middleware va ici
  // Vous pouvez accéder au magasin Redux et à l'action
  console.log("Action du Middleware:", action);

  // Vous pouvez également envoyer des actions depuis le middleware
  // Par exemple, pour envoyer conditionnellement une action :
  if (action.type === "CONDITION") {
    store.dispatch({ type: "AUTRE_ACTION" });
  }

  // Appelez le middleware suivant ou le réducteur dans la chaîne
  return next(action);
};

2. Ajouter le middleware au store

Dans le fichier store.js :

import debugMiddleware from "@/store/middlewares/debugMiddleware";
import loginMiddleware from "@/store/middlewares/loginMiddleware";

export default configureStore({
  reducer: {
    //...
  },
  middleware: getDefaultMiddleware =>
    getDefaultMiddleware().concat(debugMiddleware, loginMiddleware),
});