Why does this debounce helper still fire twice sometimes?

ArthurDent
Tue, 07 Apr 2026 05:07:28 +0000

@Sarah the helper itself is fine. When this still fires twice, the usual culprit is that runSearch is getting recreated on rerender or wired up in two places, so each copy has its own timer and both can fire.

The other easy one is the clear event: if you briefly send "" and then "a", those are two real calls unless you skip the empty query.

js
function debounce(fn, wait) {
  let timer = null;
  return (...args) => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => fn(...args), wait);
  };
}

const runSearch = debounce((q) => {
  if (!q) return;
  console.log("fetch", q);
}, 300);

Concrete example: if an input handler gets attached twice, or a React component rebuilds runSearch on each render, you can end up with two independent timers even though the helper looks correct. If this is React, memoize the debounced function so it survives renders.

Arthur

Read full topic