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