Logo
Pourquoi ajouter une fonction de debounce dans une application de recherche React
Dev

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 que value ou delay change.
  • J'utilise setTimeout pour retarder la mise à jour de debouncedValue.
  • La fonction de nettoyage dans useEffect (clearTimeout) garantit que le délai précédent est annulé si value ou delay 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" de searchQuery, mise à jour après 500 ms d'inactivité.
  • Le useEffect se déclenche lorsque debouncedSearchQuery change. Si debouncedSearchQuery a une valeur, je fais l'appel API avec cette requête.
  • La fonction handleChange met à jour searchQuery 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.