0
0
ReactHow-ToBeginner · 4 min read

How to Debounce Event Handler in React: Simple Guide

To debounce an event handler in React, wrap the handler function with a debounce utility that delays its execution until the user stops triggering the event for a set time. You can use libraries like lodash.debounce or create a custom hook with setTimeout and clearTimeout inside a functional component.
📐

Syntax

Debouncing delays calling a function until after a pause in events. In React, you typically use a debounce function that takes your event handler and a delay time in milliseconds.

  • handler: The function to run after the delay.
  • delay: Time in ms to wait before running the handler.
  • debouncedHandler: The new function you use in your event, which delays calls.
javascript
import debounce from 'lodash.debounce';

const debouncedHandler = debounce(handler, delay);
💻

Example

This example shows a React input field where the handleChange event is debounced by 500ms. The displayed value updates only after the user stops typing for half a second.

javascript
import React, { useState, useMemo, useEffect } from 'react';
import debounce from 'lodash.debounce';

export default function DebouncedInput() {
  const [value, setValue] = useState('');

  const debouncedChangeHandler = useMemo(() =>
    debounce((event) => {
      setValue(event.target.value);
    }, 500), []);

  useEffect(() => {
    return () => {
      debouncedChangeHandler.cancel();
    };
  }, [debouncedChangeHandler]);

  return (
    <div>
      <input
        type="text"
        onChange={debouncedChangeHandler}
        placeholder="Type here..."
        aria-label="Debounced input"
      />
      <p>Debounced value: {value}</p>
    </div>
  );
}
Output
An input box appears. When typing, the displayed text below updates only after 500ms pause in typing.
⚠️

Common Pitfalls

Common mistakes when debouncing in React include:

  • Creating a new debounced function on every render, which resets the timer and prevents debouncing.
  • Not cleaning up the debounced function on unmount, causing memory leaks.
  • Using debounced functions directly inside JSX without memoization.

Always use useMemo or useCallback to keep the debounced function stable across renders.

javascript
/* Wrong: new debounce on every render */
function Wrong() {
  const debounced = debounce(() => console.log('Hi'), 300);
  return <button onClick={debounced}>Click</button>;
}

/* Right: memoize debounce */
import { useMemo } from 'react';
function Right() {
  const debounced = useMemo(() => debounce(() => console.log('Hi'), 300), []);
  return <button onClick={debounced}>Click</button>;
}
📊

Quick Reference

  • Use lodash.debounce or write a custom debounce hook.
  • Wrap your handler with debounce and memoize it with useMemo or useCallback.
  • Clean up debounced functions on unmount if needed.
  • Debouncing improves performance by limiting how often handlers run during rapid events.

Key Takeaways

Debounce delays event handler calls until user stops triggering events for a set time.
Use lodash.debounce with useMemo or useCallback to avoid recreating debounce on every render.
Always memoize debounced handlers to keep them stable and prevent bugs.
Debouncing improves app performance and user experience by reducing unnecessary updates.
Clean up debounced functions on component unmount to avoid memory leaks.