javascriptreactjsdebouncing

Working of useSearchDebounce custom react hook


I found this code from this answer https://stackoverflow.com/a/68780417/26420821

How does it work?

export function useSearchDebounce(delay = 350) {
  const [search, setSearch] = useState(null);
  const [searchQuery, setSearchQuery] = useState(null);

  useEffect(() => {
    const delayFn = setTimeout(() => {
        console.log("setTimeout called");
        setSearch(searchQuery);
    }, delay);

    return () => clearTimeout(delayFn);
  }, [searchQuery, delay]);

  return [search, setSearchQuery];
}

Usage :

const [search, setSearch] = useSearchDebounce();

<input onChange={(e) => setSearch(e.target.value)}/>

If we assume user types "abc" together in the input field with delay set to 5000,

At first, searchQuery will be "a" , it will setTimeout() to run after 5 secs,

Then searchQuery will be "ab" , it will again setTimeout() to run after 5 secs,

Then searchQuery will be "abc" , it will again setTimeout() to run after 5 secs

But when I tested console.log() executed just once, Why didn't setTimeout() execute 3 times ?

Am I misunderstanding something ?

I don't understand the code


Solution

  • But when I tested console.log() executed just once, Why didn't setTimeout() execute 3 times ?

    Because every time one of your dependencies change (ie: searchQuery or delay), the cleanup function is first ran clearing the previous timeout that had been scheduled, then it runs your useEffect callback to schedule a new timeout.

    So the behaviour you're missing is that the previous timeout is cleared when the user types "abc":

    Timeout completes as nothing clears it and you see the setTimeout called log.