Evite sobrecarregar o servidor com chamadas de função de pesquisa desnecessárias e otimize o desempenho do seu aplicativo usando esta técnica.
No React, ao implementar a funcionalidade de pesquisa, o manipulador onChange chama a função de pesquisa toda vez que o usuário digita dentro da caixa de entrada. Essa abordagem pode causar problemas de desempenho, especialmente ao fazer chamadas de API ou consultar o banco de dados. Chamadas frequentes para a função de pesquisa podem sobrecarregar o servidor web, causando travamentos ou falta de resposta da interface do usuário. Debouncing resolve esse problema.
O que é Debouncing?
Normalmente, você implementa a funcionalidade de pesquisa no React chamando uma função manipuladora onChange a cada pressionamento de tecla, conforme mostrado abaixo:
import { useState } from"react";
exportdefaultfunctionSearch() {
const [searchTerm, setSearchTerm] = useState("");const handleSearch = () => {
console.log("Search for:", searchTerm);
};const handleChange = (e) => {
setSearchTerm(e.target.value);
// Calls search function
handleSearch();
};
return (
onChange={handleChange}
value={searchTerm}
placeholder="Search here..."
/>
);
}
Embora isso funcione, a chamada ao back-end para atualizar os resultados da pesquisa a cada pressionamento de tecla pode sair cara. Por exemplo, se você estivesse procurando por “webdev”, a aplicação enviaria uma solicitação ao backend com os valores “w”, “nós”, “web” e assim por diante.
Debouncing é uma técnica que funciona atrasando a execução de uma função até que um período de atraso tenha decorrido. A função debounce detecta toda vez que o usuário digita e evita a chamada para o manipulador de pesquisa até que o atraso tenha decorrido. Se o usuário continuar digitando dentro do período de atraso, o cronômetro será zerado e o React chamará a função novamente para o novo atraso. Esse processo continua até que o usuário faça uma pausa na digitação.
Ao esperar que os usuários pausem a digitação, o debouncing garante que seu aplicativo faça apenas as solicitações de pesquisa necessárias, reduzindo assim a carga do servidor.
Como rejeitar a pesquisa no React
Existem várias bibliotecas que você pode usar para implementar o debounce. Você também pode optar por implementá-lo do zero usando JavaScript setTimeout e limparTimeout funções.
Este artigo usa a função debounce de a biblioteca lodash.
Supondo que você tenha um projeto React pronto, crie um novo componente chamado Procurar. Se você não tiver um projeto em funcionamento, crie um aplicativo React usando o criar utilitário de aplicativo React.
No Procurar arquivo de componente, copie o código a seguir para criar uma caixa de entrada de pesquisa que chama uma função de manipulador em cada pressionamento de tecla.
import { useState } from"react";
exportdefaultfunctionSearch() {
const [searchTerm, setSearchTerm] = useState("");const handleSearch = () => {
console.log("Search for:", searchTerm);
};const handleChange = (e) => {
setSearchTerm(e.target.value);
// Calls search function
handleSearch();
};
return (
onChange={handleChange}
value={searchTerm}
placeholder="Search here..."
/>
);
}
Para desbancar o identificadorSearch função, passe-a para o rebater função de lodash.
import debounce from"lodash.debounce";
import { useState } from"react";exportdefaultfunctionSearch() {
const [searchTerm, setSearchTerm] = useState("");const handleSearch = () => {
console.log("Search for:", searchTerm);
};
const debouncedSearch = debounce(handleSearch, 1000);const handleChange = (e) => {
setSearchTerm(e.target.value);
// Calls search function
debouncedSearch();
};
return (
onChange={handleChange}
value={searchTerm}
placeholder="Search here..."
/>
);
}
No rebater função, você está passando a função que deseja atrasar, ou seja, o identificadorSearch função e o tempo de atraso em milissegundos, ou seja, 500 ms.
Embora o código acima deva atrasar a chamada para o identificadorSearch request até que o usuário pause a digitação, isso não funciona no React. Explicaremos o porquê na seção seguinte.
Debouncing e Rerenderizações
Este aplicativo usa uma entrada controlada. Isto significa que o valor do estado controla o valor da entrada; toda vez que um usuário digita no campo de pesquisa, o React atualiza o estado.
No React, quando um valor de estado muda, o React renderiza novamente o componente e executa todas as funções dentro dele.
No componente de pesquisa acima, quando o componente é renderizado novamente, o React executa a função debounce. A função cria um novo cronômetro que monitora o atraso e o cronômetro antigo fica na memória. Quando o tempo passa, ele aciona a função de busca. Isso significa que a função de pesquisa nunca é cancelada, ela é atrasada em 500 ms. Este ciclo se repete a cada renderização - a função cria um novo cronômetro, o cronômetro antigo expira e então chama a função de pesquisa
Para que a função debounce funcione, você precisa chamá-la apenas uma vez. Você pode fazer isso chamando a função debounce fora do componente ou usando a técnica de memoização. Dessa forma, mesmo que o componente seja renderizado novamente, o React não o executará novamente.
Definindo a função Debounce fora do componente de pesquisa
Mova o rebater funcionar fora do Procurar componente conforme mostrado abaixo:
import debounce from"lodash.debounce"const handleSearch = (searchTerm) => {
console.log("Search for:", searchTerm);
};
const debouncedSearch = debounce(handleSearch, 500);
Agora, no Procurar componente, chamada debouncedSearch e passe o termo de pesquisa.
exportdefaultfunctionSearch() {
const [searchTerm, setSearchTerm] = useState("");const handleChange = (e) => {
setSearchTerm(e.target.value);
// Calls search function
debouncedSearch(searchTerm);
};
return (
onChange={handleChange}
value={searchTerm}
placeholder="Search here..."
/>
);
}
A função de pesquisa só será chamada após decorrido o período de atraso.
Memorizando a função Debounce
Memoizar refere-se a armazenar em cache os resultados de uma função e reutilizá-los quando você chama a função com os mesmos argumentos.
Para memorizar o rebater função, use o useMemo gancho.
import debounce from"lodash.debounce";
import { useCallback, useMemo, useState } from"react";exportdefaultfunctionSearch() {
const [searchTerm, setSearchTerm] = useState("");const handleSearch = useCallback((searchTerm) => {
console.log("Search for:", searchTerm);
}, []);const debouncedSearch = useMemo(() => {
return debounce(handleSearch, 500);
}, [handleSearch]);const handleChange = (e) => {
setSearchTerm(e.target.value);
// Calls search function
debouncedSearch(searchTerm);
};
return (
onChange={handleChange}
value={searchTerm}
placeholder="Search here..."
/>
);
}
Observe que você também embrulhou o identificadorSearch funcionar em um useCallback hook para garantir que o React o chame apenas uma vez. Sem o useCallback gancho, o React executaria o identificadorSearch função com cada re-renderização fazendo as dependências do useMemo mudança de gancho que por sua vez chamaria o rebater função.
Agora, o React só chamará o rebater funcionar se o identificadorSearch função ou o tempo de atraso muda.
Otimize a pesquisa com Debounce
Às vezes, desacelerar pode ser melhor para o desempenho. Ao lidar com tarefas de pesquisa, especialmente com chamadas caras de banco de dados ou API, usar uma função debounce é a melhor opção. Esta função introduz um atraso antes de enviar solicitações de backend.
Ajuda a reduzir o número de solicitações feitas ao servidor, pois só envia a solicitação depois de decorrido o atraso e o usuário pausar a digitação. Dessa forma, o servidor não fica sobrecarregado com muitas solicitações e o desempenho permanece eficiente.