Les middlewares ne sont pas un concept nouveau en développement web. Ils sont généralement associés à des frameworks côté serveur comme Express.js, où il y a beaucoup d’authentification, de journalisation, etc. En raison de ses avantages inhérents, les middlewares ont gagné en popularité dans le frontend.
Des frameworks frontend tels que React l’adoptent comme moyen de gérer des fonctionnalités complexes lors de la gestion de l’état. Dans ce guide, nous vous guiderons à travers le concept de middleware dans React et comment l’utiliser pour améliorer la fonctionnalité de votre application React et gérer efficacement le flux de l’application.
À la fin, vous aurez une bonne compréhension de ce qu’est le middleware React et comment l’implémenter avec Redux Thunk.
Middleware React Simplifié : Rationaliser la Logique de l’Application
Qu’est-ce que le Middleware ?
Comme son nom l’indique, le middleware est une couche qui se situe entre différents composants d’une application. Il fournit une couche de traitement et de fonctionnalité là où il n’y en aurait pas sans lui. Le middleware fonctionne en interceptant les requêtes circulant d’un composant à un autre et vous permet d’effectuer des actions spécifiques. Une fois terminé, il transmet la requête modifiée au prochain middleware ou à sa destination prévue.
Il s’agit d’un concept principalement utilisé côté serveur. Mais, comme mentionné précédemment, il a été adapté dans React pour servir un but similaire. Maintenant, plongeons dans ce que signifie le middleware, spécifiquement dans React.
Middleware dans React
En React, le middleware est implémenté sous forme d’une série de fonctions, exécutées les unes après les autres, dans l’ordre que vous définissez. Chaque fonction a accès à l’état de l’application et aux actions. Ainsi, les fonctions peuvent modifier et envoyer de nouvelles actions.
Lorsque l’état change en React, l’application envoie des actions qui sont ensuite gérées par le(s) Réducteur(s). Le(s) Réducteur(s) renverront alors un nouvel état, qui est ensuite stocké et renvoyé à l’application.
Le middleware React se place entre l’action envoyée et l’intercepte avant qu’elle n’atteigne le réducteur. Ensuite, il vous permet de vous connecter à ce processus et d’exécuter du code sur cette action, par exemple en la journalisant ou en effectuant un appel API.
Une fois cela fait, il transmettra l’action modifiée au Réducteur (s’il n’y a pas d’autre middleware dans la chaîne).
Exemples de Middleware en React
Vous pouvez trouver des middlewares React principalement dans Redux, la bibliothèque React de gestion d’état complexe. Redux a deux types principaux de middleware :
- Thunk – nous approfondirons comment utiliser ce middleware pour modifier une action.
- Saga.
Chacun d’eux gère différents types de modifications d’actions, comme nous le verrons ci-dessous en examinant les utilisations de middleware en React. D’autres bibliothèques React, telles que React Query, utilisent également des middlewares (nous en parlerons plus tard).
Avant d’examiner comment implémenter ceci, passons en revue les différentes utilisations de middleware en React.
Utilisations de Middleware en React
React middleware est utile pour les cas d’utilisation suivants :
Debugging et Logging
Les middlewares React peuvent être utilisés pour enregistrer des informations telles que l’état actuel, les actions et d’autres données lors du développement de l’application. De plus, ils peuvent être utiles pour identifier les bogues potentiels et les erreurs pour une résolution précoce.
Le Redux Logger (pour Redux) peut vous aider à faire cela. Il enregistre les actions Redux et les changements d’état pour un débogage facile. Il intercepte chaque action envoyée et enregistre l’état précédent, l’action et l’état suivant.
Autorisation et Authentification
Si vous souhaitez authentifier les utilisateurs avant de mettre à jour l’état, vous pouvez utiliser Redux Thunk ou Saga pour gérer les workflows d’authentification. Une fois que vous interceptez une action, ce middleware vous permet de stocker des jetons, de vérifier l’authentification avant de dispatcher l’action, ou de rafraîchir les jetons.
En d’autres termes, ces middlewares sont utiles pour vérifier si un utilisateur est authentifié pour accéder à une route particulière ou non.
Opérations basées sur les événements
Le réducteur React est conçu pour exécuter du code synchrone. Cela signifie que si vous tentez d’exécuter quelque chose de asynchrone dessus, cela ne fonctionnera pas. Avec des middlewares React tels que Redux Thunk, vous pouvez intercepter l’action, effectuer des tâches asynchrones comme appeler une API, et passer au réducteur une fois cela fait.
Mise en cache des données
React Query (un autre middleware React) peut servir d’outil efficace pour mettre en cache les données de l’application. Il met en cache automatiquement les réponses de l’API et les révalide lorsque nécessaire. En conséquence, il vous permet d’éviter les appels d’API redondants en vérifiant les informations requises dans le cache.
Amélioration des performances
Le middleware React peut également aider à améliorer les performances de l’application en retardant les actions inutiles pour plus tard, en déclenchant des événements de manière groupée, et en traitant par lots certaines tâches. En mettant en cache les réponses de l’API, React Query améliore également les performances de vos applications React.
Comment utiliser les middlewares en React ?
Redux est un outil puissant pour gérer l’état global dans les applications React. Il inclut plusieurs middlewares dans sa boîte à outils que vous pouvez utiliser pour ajouter des fonctionnalités personnalisées à vos applications React. L’un des plus courants est Redux Thunk.
Introduction à Redux Thunk
Avant de plonger dans la mise en œuvre de Thunk, recueillons des informations à son sujet afin de pouvoir l’utiliser efficacement.
Qu’est-ce que Thunk ?
En programmation générale, un « Thunk » est simplement une fonction utilisée pour retarder l’évaluation et l’exécution d’une fonction. Nous pouvons le voir comme une fonction qui reporte une action jusqu’à ce qu’une condition spécifique soit remplie.
Dans Redux, un thunk est une fonction spécifique utilisée avec le middleware Redux Thunk. Redux Thunk est conçu pour permettre des opérations asynchrones au sein de votre application React. Plus tôt, nous avons mentionné que le Reducer est conçu pour exécuter du code synchrone. Cela signifie que lorsque une action est envoyée, le reducer met à jour l’état immédiatement.
Redux Thunk en tant que Middleware
Redux Thunk agit en tant que middleware. Il vous permet d’écrire des créateurs d’actions qui retournent des fonctions (thunks) au lieu d’objets d’action simples. Ces fonctions peuvent contenir une logique asynchrone. Lorsque vous envoyez un thunk, le middleware Thunk l’intercepte et exécute la fonction.
À l’intérieur du thunk
, vous pouvez effectuer votre opération asynchrone (par exemple, effectuer un appel API) puis envoyer des actions régulières pour mettre à jour le magasin Redux une fois l’opération terminée.
Remarque: Redux Thunk permet à la fois des opérations asynchrones et synchrones, bien que son objectif principal soit de faciliter les actions asynchrones. Il ne vous empêche pas d’envoyer des actions synchrones ; il fournit simplement un mécanisme pour gérer également les actions asynchrones.
Avec cela dit, voyons le middleware React en action en implémentant Redux Thunk.
Un guide étape par étape pour implémenter Redux Thunk
L’implémentation du middleware Redux implique les étapes suivantes :
Étape 1: Configurer Up Redux avec Thunk
Créez une application React et installez les dépendances.
npx create-react-app newApp
Étape 2: Installer Redux Thunk
Exécutez la commande suivante pour installer Redux Thunk.
npm install redux-thunk
Étape 3: Activer le Middleware Thunk
Enable the Thunk middleware in the Redux store.
import { configureStore } from '@reduxjs/toolkit';
import thunk from 'redux-thunk';
import rootReducer from './reducers'; // Combine all reducers here
const store = configureStore({
reducer: rootReducer,
middleware: [thunk],
});
export default store;
Remarque : Lorsque vous utilisez Redux Toolkit, il n’est pas nécessaire d’installer thunk
explicitement.
Étape 4 : Écriture de la fonction asynchrone
Un thunk renvoie une autre fonction qui reçoit les arguments dispatch
et getstate
pour lire l’état ou déclencher des actions. Voici un exemple de code pour récupérer des données :
// Types d'actions
const START_FETCH = 'START_FETCH';
const FETCH_SUCCESS = 'FETCH_SUCCESS';
const FETCH_ERROR = 'FETCH_ERROR';
// Créateurs d'actions
const startFetch = () => ({ type: START_FETCH });
const fetchSuccess = (data) => ({ type: FETCH_SUCCESS, payload: data });
const fetchError = (error) => ({ type: FETCH_ERROR, payload: error });
// Action de thunk
export const fetchData = () => {
return async (dispatch, getState) => {
dispatch(startFetch()); // Notify that the fetch has started
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
if (!response.ok) {
throw new Error('Failed to fetch data');
}
const data = await response.json();
dispatch(fetchSuccess(data)); // Send the fetched data to the store
} catch (error) {
dispatch(fetchError(error.message)); // Handle any errors
}
};
};
Étape 5 : Gestion des actions déclenchées dans le réducteur
Gérez les actions déclenchées en mettant à jour le réducteur.
const initialState = {
data: [],
isLoading: false,
error: null,
};
export const dataReducer = (state = initialState, action) => {
switch (action.type) {
case START_FETCH:
return { ...state, isLoading: true, error: null };
case FETCH_SUCCESS:
return { ...state, isLoading: false, data: action.payload };
case FETCH_ERROR:
return { ...state, isLoading: false, error: action.payload };
default:
return state;
}
};
Étape 6 : Déclenchement d’un thunk depuis un composant
Utilisez le crochet useDispatch
pour déclencher des thunks dans les projets React.
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchData } from './actions';
const DataComponent = () => {
const dispatch = useDispatch();
const { data, isLoading, error } = useSelector((state) => state.data);
useEffect(() => {
dispatch(fetchData()); // Trigger the thunk to fetch data
}, [dispatch]);
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return (
<ul>
{data.map((item) => (
<li key={item.id}>{item.title}</li>
))}
</ul>
);
};
export default DataComponent;
Utilisation de createAsyncThunk
Redux Toolkit contient une API intégrée qui définit la logique de haut niveau pour les fonctions asynchrones, les déclenche et gère les erreurs rapidement. Veuillez noter que cela fournit une abstraction pour les cas d’utilisation spécifiques des fonctions asynchrones, createAsyncThunk
ne s’applique pas à tous les cas d’utilisation des thunks.
Voici un exemple d’implémentation de createAsyncThunk
:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
export const dataFetch = createAsyncThunk('data/fetchData', async () => {
const response = await fetch('https://api.example.com/data');
return response.json();
});
const dataSlice = createSlice({
name: 'data',
initial_State: { data: [], loading: false, error: null },
extraReducers: (builder) => {
builder
.addCase(dataFetch.pending, (state) => {
state.loading = true;
state.error = null;
})
.addCase(dataFetch.fulfilled, (state, action) => {
state.loading = false;
state.data = action.payload;
})
.addCase(dataFetch.rejected, (state, action) => {
state.loading = false;
state.error = action.error.message;
});
},
});
export default dataSlice.reducer;
Maintenant, pour déclencher le thunk dataFetch
, utilisez le code suivant :
dispatch(dataFetch ());
Utilisations du middleware React – Redux Thunk
Les thunks peuvent être utilisés pour diverses raisons, notamment mais pas uniquement :
- Abstraction de la logique complexe des composants.
- Effectuer des requêtes asynchrones et de la logique.
- Écrire des fonctions pour déclencher plusieurs actions en série.
Les middlewares React dans d’autres bibliothèques de gestion d’état
Redux n’est pas la seule bibliothèque React qui utilise des middlewares. Vous pouvez également les trouver dans d’autres bibliothèques de gestion d’état, bien que la mise en œuvre de ce concept dans ces bibliothèques soit différente de celle de Redux.
MobX
MobX n’a pas de middleware traditionnel comme Redux. Il offre des fonctionnalités similaires à travers des mécanismes tels que les intercepteurs, les observateurs et les réactions. Ces mécanismes vous permettent d’observer les changements dans votre état MobX et d’y réagir. De cette manière, MobX propose des moyens de gérer les effets secondaires, le journalisation et d’autres tâches que les middlewares gèrent généralement dans Redux.
Recoil
Recoil ne prend pas en charge les middlewares de la même manière que Redux car ce n’est pas nécessaire. Il vous permet de mettre à jour directement des morceaux d’état (atomes) en utilisant des fonctions spécifiques. Il n’y a pas de dispatching d’actions vers un réducteur, que vous pouvez intercepter avec un middleware. Pour gérer les opérations asynchrones, il utilise des sélecteurs – un état dérivé dépendant des atomes ou d’autres sélecteurs.
Zustand
Cela aide à gérer les états avec une API simple et prend en charge les middlewares natifs pour la journalisation et le stockage des états, tout comme Redux.
XState
XState prend en charge un comportement similaire à celui des middlewares en utilisant des hooks tels que onTransition
, actions
, et services
. Ces hooks aident à intercepter et à modifier les transitions d’état.
Conclusion
Les middleware agissent comme un pont pour connecter et combiner différents composants d’une application web afin d’améliorer le flux et la gestion des données. Ils sont largement utilisés côté serveur depuis longtemps, mais ont maintenant trouvé des cas d’utilisation côté client également.
Dans React, il existe différentes façons de mettre en œuvre les middleware. Ils sont généralement liés aux bibliothèques de gestion de l’état telles que Redux et MobX. Le middleware React le plus couramment utilisé, Thunk, est inclus dans la bibliothèque Redux. Un thunk est un bloc de code qui effectue des tâches différées.
Dans cet article, nous avons exploré les middleware dans React, la bibliothèque Redux et Redux Thunk. Nous avons également couvert les étapes pour implémenter le middleware Redux Thunk pour récupérer des données et dispatcher des actions.
Source:
https://dzone.com/articles/demystifying-react-middleware-bridging-apis-and-co