Debouncing with React Hooks

Hoy les voy a mostrar cómo crear un enlace useDebounce que le permita aplazar súper simplemente las llamadas a la API para que no sucedan con demasiada frecuencia.


También creé una demostración que usa nuestro gancho. Busca las API de Marvel Comics y el enlace useDebounce le permite evitar las llamadas al servidor por cada pulsación de tecla.


imagen


Bastante elegante, ¿eh? Ok, ahora vamos al código!


, , . , , , . useEffect, , . useState useEffect, .


import React, { useState, useEffect } from 'react';
import useDebounce from './use-debounce';

// 
function App() {
  //       
  const [searchTerm, setSearchTerm] = useState('');
  //       
  const [results, setResults] = useState([]);
  //     (    API)
  const [isSearching, setIsSearching] = useState(false);

  //     ,    searchTerm.
  //      (  ) ...
  // ...    500ms   .
  //      searchTerm.
  //   ,      ,    
  //           .
  const debouncedSearchTerm = useDebounce(searchTerm, 500);

  //    
  //   useEffect,     
  useEffect(
    () => {
      //       (  -)
      if (debouncedSearchTerm) {
        //   isSearching
        setIsSearching(true);
        //    
        searchCharacters(debouncedSearchTerm).then(results => {
          //    false, -  
          setIsSearching(false);
          //    
          setResults(results);
        });
      } else {
        setResults([]);
      }
    },
    //    useEffect
    //  useEffect       ...
    // ...    ,      ...
    //   searchTerm     500ms.
    [debouncedSearchTerm]
  );

  //   UI     
  return (
    <div>
      <input
        placeholder="Search Marvel Comics"
        onChange={e => setSearchTerm(e.target.value)}
      />

      {isSearching && <div>Searching ...</div>}

      {results.map(result => (
        <div key={result.id}>
          <h4>{result.title}</h4>
          <img
            src={`${result.thumbnail.path}/portrait_incredible.${
              result.thumbnail.extension
            }`}
          />
        </div>
      ))}
    </div>
  );
}

//    
function searchCharacters(search) {
  const apiKey = 'f9dfb1e8d466d36c27850bedd2047687';
  const queryString `apikey=${apiKey}&titleStartsWith=${search}`;
  return fetch(
    `https://gateway.marvel.com/v1/public/comics?${queryString}`,
    {
      method: 'GET'
    }
  )
    .then(r => r.json())
    .then(r => r.data.results)
    .catch(error => {
      console.error(error);
      return [];
    });
}

, ! , .


import React, { useState, useEffect } from 'react';

//  
export default function useDebounce(value, delay) {
  //      
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(
    () => {
      //  debouncedValue  value ( ) 
      //   
      const handler = setTimeout(() => {
        setDebouncedValue(value);
      }, delay);

      //   ,     ,  ...
      // ... useEffect  . useEffect   ,   ...
      // ... value   (   ).
      //     debouncedValue,   value ...
      // ...     .
      //     .
      //     :    -  ...
      // ...     ,   ,  debouncedValue...
      // ...     ,      ,  500ms.
      return () => {
        clearTimeout(handler);
      };
    },
    //  ,    
    //       "delay"    ...
    // ...      .
    [value]
  );

  return debouncedValue;
}

¡Y aquí está él delante de ti! Ahora tenemos un enlace para valores diferidos con el que podemos retrasar el cambio de cualquier valor directamente en el cuerpo de nuestro componente. El valor diferido se puede agregar a la matriz de dependencia useEffect, en lugar de los valores mutables, para limitar la frecuencia de las llamadas al efecto deseado.


Aquí está la demostración demo de Marvel Comic Search en CodeSandbox.


Si te gustó, puedes echar un vistazo y calificar mi blog sobre React hooks y el generador de aplicaciones React.


All Articles