Testando debounce e throttle no React com Jest [setTimeout]

Implementar debounce ou throttle no React é comum em buscas, inputs e eventos de scroll. Mas testar esse comportamento pode parecer desafiador à primeira vista — especialmente por envolver tempo, timers assíncronos e side effects.

Neste artigo, você v…


This content originally appeared on DEV Community and was authored by Vitor Rios

Implementar debounce ou throttle no React é comum em buscas, inputs e eventos de scroll. Mas testar esse comportamento pode parecer desafiador à primeira vista — especialmente por envolver tempo, timers assíncronos e side effects.

Neste artigo, você vai aprender:

  • Diferença entre debounce e throttle
  • Como implementá-los no React
  • Como testá-los com Jest e @testing-library/react
  • Como usar jest.useFakeTimers() do jeito certo

🔍 O que é debounce e throttle?

🐢 debounce

Adia a execução até X ms após a última chamada.

🧠 Ideal para: buscas ao digitar, auto-saves, etc.

🐇 throttle

Executa no máximo uma vez a cada X ms, ignorando chamadas subsequentes.

🧠 Ideal para: scroll, resize, cliques rápidos, etc.

🧱 Implementando debounce no React

// SearchInput.tsx
import { useEffect, useState } from 'react';

type Props = {
  onSearch: (query: string) => void;
};

export function SearchInput({ onSearch }: Props) {
  const [value, setValue] = useState('');

  useEffect(() => {
    const timeout = setTimeout(() => {
      onSearch(value);
    }, 500);

    return () => clearTimeout(timeout);
  }, [value, onSearch]);

  return (
    <input
      placeholder="Search..."
      value={value}
      onChange={(e) => setValue(e.target.value)}
    />
  );
}

🧪 Testando debounce com jest.useFakeTimers()

// SearchInput.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import { SearchInput } from './SearchInput';

jest.useFakeTimers();

test('calls onSearch after debounce delay', () => {
  const handleSearch = jest.fn();
  render(<SearchInput onSearch={handleSearch} />);

  const input = screen.getByPlaceholderText(/search/i);
  fireEvent.change(input, { target: { value: 'hello' } });

  // Ainda não chamou
  expect(handleSearch).not.toHaveBeenCalled();

  // Avança 500ms
  jest.advanceTimersByTime(500);

  expect(handleSearch).toHaveBeenCalledWith('hello');
});

⚡ Implementando throttle com lodash

// ThrottledButton.tsx
import { throttle } from 'lodash';
import { useCallback } from 'react';

export function ThrottledButton({ onClick }: { onClick: () => void }) {
  const throttled = useCallback(throttle(onClick, 1000), [onClick]);

  return <button onClick={throttled}>Click me fast!</button>;
}

🧪 Testando throttle com fake timers

// ThrottledButton.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import { ThrottledButton } from './ThrottledButton';

jest.useFakeTimers();

test('calls onClick only once in throttle window', () => {
  const handleClick = jest.fn();
  render(<ThrottledButton onClick={handleClick} />);

  const button = screen.getByText(/click me/i);
  fireEvent.click(button);
  fireEvent.click(button);
  fireEvent.click(button);

  expect(handleClick).toHaveBeenCalledTimes(1);

  jest.advanceTimersByTime(1000);
  fireEvent.click(button);

  expect(handleClick).toHaveBeenCalledTimes(2);
});

🧠 Dicas rápidas

  • Use jest.useFakeTimers() antes de renderizar o componente.
  • Sempre finalize com jest.useRealTimers() se for fazer outros testes depois.
  • Debounce pode ser testado com setTimeout; throttle exige lib como lodash ou lodash.throttle.

✅ Conclusão

Testar debounce e throttle é mais fácil do que parece quando você usa as ferramentas certas: fake timers + eventos simulados. Evite confiar apenas no comportamento visual — escrever testes sólidos é o que garante que seu input não dispare chamadas desnecessárias no futuro.


This content originally appeared on DEV Community and was authored by Vitor Rios


Print Share Comment Cite Upload Translate Updates
APA

Vitor Rios | Sciencx (2025-09-12T10:31:57+00:00) Testando debounce e throttle no React com Jest [setTimeout]. Retrieved from https://www.scien.cx/2025/09/12/testando-debounce-e-throttle-no-react-com-jest-settimeout/

MLA
" » Testando debounce e throttle no React com Jest [setTimeout]." Vitor Rios | Sciencx - Friday September 12, 2025, https://www.scien.cx/2025/09/12/testando-debounce-e-throttle-no-react-com-jest-settimeout/
HARVARD
Vitor Rios | Sciencx Friday September 12, 2025 » Testando debounce e throttle no React com Jest [setTimeout]., viewed ,<https://www.scien.cx/2025/09/12/testando-debounce-e-throttle-no-react-com-jest-settimeout/>
VANCOUVER
Vitor Rios | Sciencx - » Testando debounce e throttle no React com Jest [setTimeout]. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/09/12/testando-debounce-e-throttle-no-react-com-jest-settimeout/
CHICAGO
" » Testando debounce e throttle no React com Jest [setTimeout]." Vitor Rios | Sciencx - Accessed . https://www.scien.cx/2025/09/12/testando-debounce-e-throttle-no-react-com-jest-settimeout/
IEEE
" » Testando debounce e throttle no React com Jest [setTimeout]." Vitor Rios | Sciencx [Online]. Available: https://www.scien.cx/2025/09/12/testando-debounce-e-throttle-no-react-com-jest-settimeout/. [Accessed: ]
rf:citation
» Testando debounce e throttle no React com Jest [setTimeout] | Vitor Rios | Sciencx | https://www.scien.cx/2025/09/12/testando-debounce-e-throttle-no-react-com-jest-settimeout/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.