Create a Debounced Event Handler with the useMemo Hook

Share this video with your friends

Send Tweet

Our class-based component relies on instance variables to ensure it's only created once.

this.amountChanged = debounce(this.props.changeAmount, 500);

Functional components aren't classes and therefore don't have instance variables. Because of that it might seem like a good idea to write your component like this:

// BAD EXAMPLE
const onAmountChanged = debounce(changeAmount, 500);

This has the problem of executing the debounce function on each render, creating many new onAmountChanged functions. Instead we're going to use the useMemo hook, which will only execute the debounce method when the dependencies change, which in this case is just on first render.

const onAmountChanged = useMemo(() => debounce(changeAmount, 500), []);

Lastly we note the warning that we did not include a dependency in our method. This is a friendly lint warning that in practice doesn't always need to be heeded. However we end up adding the changeAmount prop to our dependencies array, just in case the prop ends up changing, so we get an updated onAmountChanged varible.

Our final debounced method ends up looking like this:

const onAmountChanged = useMemo(() => debounce(changeAmount, 500), [changeAmount]);

The "memo" in useMemo is short for memoization. Memoization is a programming technique for making code more efficient by remembering past values. You can learn more about it here: https://reactjs.org/docs/hooks-reference.html#usememo