Avoid multiple clicks using debounce with react hooks
Why debounce with react hooks? We all come across that one button users keep on pressing until the data is loaded. Without guarding your code with every sort of if conditions, you can guard this by debouncing. For multiple tap scenarios, you can either propagate the event at the first tap/click or the last one.
Debouncing with hooks can be a bit tricky to sort out. The problem is the functional components in react will initialize the function when rendering. To avoid that and register a debouncing function you can use the following method.
How to use debounce with react hooks
We will be using the lodash debounce function https://lodash.com/docs/4.17.4 to debounce and avoid multiple tap action. In this simple example, a tap on the button will be used to explain how to use the debounce function.
Here we use useCallback
hook to avoid updating the debounce function when re-rendering the component on state change. This is very important in these kind of implementations to avoid initializing functions every time when renders or state changes.
Note that we have passed clicks
as a parameter to avoid the debounce function using the initial values in the function callback. For these kinds of state updates, you may need to use a closure that can be updated from parameters provided to the debounce function.
const {useState, useCallback } = React;
const INTERVAL = 1000;
const Button = ({label, onClick}) => {
return (
<div className="button" onClick={onClick}>{label}</div>
);
}
const App = () => {
const [clicks, setClicks] = useState(0);
// Add once click to the existing state value
const clickOnce = (click) => {
setClicks(click + 1);
}
// debounce the click function
// note that the clicks are passed as a parameter to avoid repeating the initial value
const debouncedClick = useCallback(_.debounce((clicks) => {
clickOnce(clicks);
}, INTERVAL, {leading: true, trailing: false, maxWait: INTERVAL}), []);
return (
<div>
<Button label="Click Button" clicks={clicks} onClick={() => debouncedClick(clicks)}/>
<div className="click-count">Click Count: {clicks}</div>
</div>
);
};
ReactDOM.render(
<App />,
document.getElementById('app')
);
Above is the codepen example. Here we have used an extra button component to increase the count. When you tapping the button, you will notice that the count is increased every second which is the INTERVAL const declared at the beginning of the js script. Also, you can use different kinds of options to suit your needs. The maxWait
and interval
are two important parameters you would need to understand better as well.
See the Pen Debounce using React hooks by Sandaruwan Nanayakkara (@sandaruny) on CodePen.
Also if you need to use debounce on react component class checkout following link: