Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 344
gacat Avatar asked May 02 '21 07:05

gacat


People also ask

What is debounce callback?

When making the switch from off to on, the signal “bounces”. So “debouncing” is just cleaning up this noise. The system debounces this signal by only reacting to the new state when the signal has stayed the same for a certain minimum amount of time.

What is the use of useCallback?

useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. shouldComponentUpdate ).

What is useCallback in React with example?

The React useCallback Hook returns a memoized callback function. Think of memoization as caching a value so that it does not need to be recalculated. This allows us to isolate resource intensive functions so that they will not automatically run on every render.


1 Answers

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.

like image 58
Dennis Vash Avatar answered Oct 19 '22 13:10

Dennis Vash