Throttling and debouncing let us slow down the running of code in different ways.
Debounce means we run a piece of code after a given timeout interval.
Throttling means that we don’t let a piece of code run more than one in a given period.
In this article, we’ll look at how to add throttle and denounce to our React components created with React hooks.
Debounce
We can run a piece of code once after a given time interval by adding a timer to throttle the number of times a piece of code runs within a period.
For example, we can write:
import { useCallback, useEffect, useState } from "react";
const useDebouncedEffect = (effect, delay, deps) => {
const callback = useCallback(effect, [...deps, effect]);
useEffect(() => {
const handler = setTimeout(() => {
callback();
}, delay);
return () => {
clearTimeout(handler);
};
}, [callback, delay]);
};
export default function App() {
const [value, setValue] = useState(0);
useDebouncedEffect(() => console.log(value), 1000, [value]);
return (
<>
<button onClick={() => setValue(value + 1)}>increment</button>
<p>{value}</p>
</>
);
}
to create the useDebouncedEffect
hook to let us run the the effect
function with a delay.
It takes the effect
callback function, the delay
value in milliseconds, and the deps
array of dependencies to watch to update the callback.
In the hook, we call useCallback
with effect
and depts
to create a function that’s re-created with deps
or effect
changes.
Then we call useEffect
with a callback to call callback
with a delay
with setTimeout
.
And we return a function that calls clearTimeout
to clear the timer.
We watch the callback
and delay
in the useEffect
hook to run the useEffect
callback when they change.
In App
, we create the value
state.
Then we call the useDebouncedEffect
hook with the callback to do what we want.
Then we pass in the delay and the array of values to watch.
And then we display a button to update value
when we click it and display the value
itself.
Throttle
To throttle the number of times a function is run, we can use Lodash’s throttle
function.
For instance, we can write:
import { useEffect, useState } from "react";
import _ from "lodash";
export default function App() {
const [value, setValue] = useState(0);
useEffect(() => {
const log = _.throttle(() => console.log(value), 1000);
log();
}, [value]);
return (
<>
<button onClick={() => setValue(value + 1)}>increment</button>
<p>{value}</p>
</>
);
}
We create the log
function with the throttle
function with the callback we want to run.
The 2nd argument is the time interval in which the function runs once in milliseconds.
Conclusion
We can add throttling and debouncing easily with React hooks and Lodash.