I am trying to implement debounce
in my search input in React. The below code is causing the delay but its firing the same number of times.
Example - If I type abcd
in less than 2 seconds(delay) my debounced value should be abcd
instead I am getting console with all values-
Debounced: a
Debounced: ab
Debounced: abc
Debounced: abcd
What I am assuming, if I type abcd
then it should make a single call instead of 4 in this case.
Code -
import { useState } from 'react';
function debounce(cb, delay) {
let timeoutId;
return function (...args) {
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(() => {
cb(...args);
}, delay);
};
}
export default function App() {
const [searchVal, setSearchVal] = useState('');
const [debounceVal, setDebounceVal] = useState('');
const debouncedChange = debounce((inputValue) => {
console.log('Debounced:', inputValue);
setDebounceVal(inputValue);
}, 2000);
const handleChange = (e) => {
const inputValue = e.target.value;
setSearchVal(inputValue);
debouncedChange(inputValue);
};
return (
<div className="App">
<h1>Debounce</h1>
<div className="container">
<div className="search-input">
<input type="text" value={searchVal} onChange={handleChange} />
</div>
<div className="search-data">{debounceVal}</div>
</div>
</div>
);
}
Let me know if I am doing something wrong here with the code or my understanding around debounce.
I would recommend using useEffect hook to listen to any changes and do a clean-up as well. Here's a working DEMO
function useDebounce(cb, delay) {
const [debounceValue, setDebounceValue] = useState(cb);
useEffect(() => {
const handler = setTimeout(() => {
setDebounceValue(cb);
}, delay);
return () => {
clearTimeout(handler);
};
}, [cb, delay]);
return debounceValue;
}