Pourquoi ajouter une fonction de debounce dans une application de recherche React
- Date
- 14/08/2024
- Auteur
- Didier
Une fonctionnalité de debounce permet d'éviter qu'une opération soit exécutée plusieurs fois alors que ce n'est pas nécessaire.
Dans mon application, je voulais éviter d'appeler une fonction ou une API de manière répétée et excessive lors de la saisie de texte dans un champ de recherche, afin d'éviter des problèmes tels que le plantage du serveur.
Je vais reprendre un exemple que j’avais déjà réalisé pour illustrer l'utilisation du debounce en JavaScript avec un cas pratique.
Voici le lien de l'exemple précédent : https://github.com/didiergrand/simple-search-app-techwithcy
Comment j'ai ajouté le debounce à mon application React
J'ai commencé par créer une fonction useDebounce
que je pouvais utiliser pour le debounce de ma recherche.
Dans le dossier src
, j'ai créé un nouveau fichier useDebounce.js
. Voici comment j'ai implémenté cette fonction :
import { useState, useEffect } from 'react';
export default function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
}, [value, delay]);
return debouncedValue;
}
Cette fonction useDebounce
est un hook personnalisé qui prend deux arguments :
value
: la valeur que je veux "debouncer" (par exemple, la requête de recherche).delay
: le délai en millisecondes après lequel la valeur sera mise à jour.
Explication du code :
- J'utilise
useState
pour stocker la valeur "debouncée" (debouncedValue
). - Le
useEffect
se déclenche chaque fois quevalue
oudelay
change. - J'utilise
setTimeout
pour retarder la mise à jour dedebouncedValue
. - La fonction de nettoyage dans
useEffect
(clearTimeout
) garantit que le délai précédent est annulé sivalue
oudelay
change avant la fin du délai. - Le hook retourne
debouncedValue
, qui sera mis à jour après le délai spécifié.
Utilisation de useDebounce
dans mon composant
J'ai ensuite utilisé cette fonction dans mon composant App
pour "debouncer" la valeur de la requête de recherche.
import React, { useState, useEffect } from 'react';
import useDebounce from './useDebounce';
function App() {
const [searchQuery, setSearchQuery] = useState("");
const [searchResult, setSearchResult] = useState([]);
const debouncedSearchQuery = useDebounce(searchQuery, 500); // Debounce de 500ms
useEffect(() => {
if (debouncedSearchQuery) {
// Faire l'appel API ici...
fetch(`https://api.example.com/search?query=${debouncedSearchQuery}`)
.then(response => response.json())
.then(results => setSearchResult(results))
.catch(error => console.error('Erreur lors de la récupération des données :', error));
} else {
setSearchResult([]);
}
}, [debouncedSearchQuery]);
const handleChange = (event) => {
setSearchQuery(event.target.value);
};
return (
<div>
<h1>Moteur de recherche</h1>
<input
type="text"
value={searchQuery}
onChange={handleChange}
placeholder="Rechercher..."
/>
<ul>
{searchResult.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
export default App;
Explication du code :
searchQuery
: je stocke la valeur actuelle du champ de recherche.debouncedSearchQuery
: c'est la version "debouncée" desearchQuery
, mise à jour après 500 ms d'inactivité.- Le
useEffect
se déclenche lorsquedebouncedSearchQuery
change. SidebouncedSearchQuery
a une valeur, je fais l'appel API avec cette requête. - La fonction
handleChange
met à joursearchQuery
chaque fois que l'utilisateur tape dans le champ de recherche. - Les résultats de la recherche sont affichés dans une liste.
Lien vers l'exemple complet
Voici le lien vers mon exemple complet : https://github.com/didiergrand/simple-search-app-with-debounce
Conclusion
En ajoutant une fonction de debounce à mon application de recherche React, j'ai amélioré les performances en réduisant le nombre d'appels API inutiles. Cela évite de surcharger le serveur et offre une meilleure expérience utilisateur en empêchant les résultats de changer trop rapidement pendant la saisie.
J'espère que cet exemple vous sera utile.