Search code examples
reactjslodashdebouncing

explain useCallback when using debounce


When calling just the debounce function like this:

const handler = debounce(someFunction, 2000);

It will call the someFunction on every keystroke. But when we wrap it in useCallback, it works fine.

const handler = useCallback(debounce(someFunction, 2000), []);

But as far as I know debounce function should call the someFunction after 2000 ms and so the function should not be called on every keystroke. But it is not what I expected.

Can anyone explain why useCallback needed when using debounce?


Solution

  • It depends in which scope the handler defined.

    If handler defined in the outer scope of the component, it will work exactly the same:

    // Defined only once on file read
    const handler = debounce(someFunction, 2000);
    
    const Component = () => {
      return <button onClick={handler}>Run</button>;
    };
    

    But, if it is defined in the inner scope, it actually redefines the function on every render, hence you reset the debounce on every render.

    That's why on every key stroke, no debounce is applied (it resets on every render, which gives the feeling that it does not work).

    // Defined on every render
    const Component = () => {
      const handler = debounce(someFunction, 2000);
      return <button onClick={handler}>Run</button>;
    };
    

    Wrapping the function with useCallback fixes exactly that.