DEV Community

Cover image for Debouncing: Enhancing User Input Handling
cuongnp
cuongnp

Posted on

Debouncing: Enhancing User Input Handling

Hi guys! I just learned about debouncing for the first time! It might seem like a small concept, but it's incredibly useful. I have to write a post about it and share it with everyone!

What is the debouncing?

DebouncingΒ is a programming practice that limits the rate at which a function can fire. In our case, you only want to query the database when the user has stopped typing.

Use case

Imagine a search bar where users type names. We don't want to bombard the system with logic calls every time a key is pressed. Instead, we listen for the "finish typing" event (like waiting for a pause after the last keystroke). This way, our logic only activates when the user has completed their search term, delivering a more responsive experience.

How to use it?

  • I prepared a function to handle the search component like this:
'use client';

import { MagnifyingGlassIcon } from '@heroicons/react/24/outline';
import { useSearchParams, usePathname, useRouter } from 'next/navigation';

export default function Search({ placeholder }: { placeholder: string }) {


  const searchParams = useSearchParams();
  const pathname = usePathname();
  const { replace } = useRouter();

  function handleSearch(term: string) {
    console.log(`Searching... ${term}`);
    const params = new URLSearchParams(searchParams);

    if (term) {
      params.set('query', term);
    } else {
      params.delete('query');
    }
    replace(`${pathname}?${params.toString()}`)
  }

  return (
    <div className="relative flex flex-1 flex-shrink-0">
      <label htmlFor="search" className="sr-only">
        Search
      </label>
      <input
        className="peer block w-full rounded-md border border-gray-200 py-[9px] pl-10 text-sm outline-2 placeholder:text-gray-500"
        placeholder={placeholder}
        onChange={(e) => {
          handleSearch(e.target.value)
        }}
      />
      <MagnifyingGlassIcon className="absolute left-3 top-1/2 h-[18px] w-[18px] -translate-y-1/2 text-gray-500 peer-focus:text-gray-900" />
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
  • First of all, you have to install the lib use-debounce . Open your terminal and run it:
npm i use-debounce 
Enter fullscreen mode Exit fullscreen mode
  • Wrap the logic search with useDebouncedCallback:
// ...
import { useDebouncedCallback } from 'use-debounce'; // Import the useDebouncedCallback

// Inside the Search Component...
const handleSearch = useDebouncedCallback((term) => {
  console.log(`Searching... ${term}`);

  const params = new URLSearchParams(searchParams);
  if (term) {
    params.set('query', term);
  } else {
    params.delete('query');
  }
  replace(`${pathname}?${params.toString()}`);
}, 300);
Enter fullscreen mode Exit fullscreen mode

The number 300 represents the delay in milliseconds before the useDebouncedCallback function executes the provided callback function

Let me explain simply how it works:

  1. When users type in the search input, the handleSearch function is triggered
  2. useDebouncedCallback prevents the logic immediately executed.
  3. If the user continues typing within 300 milliseconds, the timer restarts, essentially resetting the delay
  4. The logic will be executed if users stop typing after 300 milliseconds

Here's the difference

  • Before
    Debouncing-before

  • After

Debouncing-before

Thanks for reading!

Top comments (0)