I have the following custom hook:
import { useEffect, useRef } from 'react';
export const useDebounce = (cb: Function, timeout: number) => {
const timeoutRef = useRef(null);
useEffect(() => {
return () => {
clearTimeout(timeoutRef.current);
};
}, []);
return (...args) => {
if (timeoutRef.current) {
console.log('clearing timeout', timeoutRef.current)
clearTimeout(timeout);
timeoutRef.current = null;
}
timeoutRef.current = setTimeout(() => {
console.log('callback invoked')
cb(...args);
}, timeout);
console.log('latest', timeoutRef.current)
};
};
and below component:
const CountriesList = () => {
const [inputValue, setIinputValue] = useState('');
const [countries, setCountries] = useState([]);
const apiCall = useCallback(async (input: string) => {
const response = await fetch(`https://.../practice/countries/${input}`);
},[]);
const debouncedApiCall = useDebounce(apiCall, 5000);
useEffect(() => {
inputValue && debouncedApiCall(inputValue);
}, [inputValue]);
const handleInput= (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
setIinputValue(value);
}
return (
<div>
<input type="text" onChange={(e)=> {handleInput(e)}} />
</div>
);
};
I was expecting the line
if (timeoutRef.current) {
console.log('clearing timeout', timeoutRef.current)
clearTimeout(timeout);
timeoutRef.current = null;
}
to clear existing timeouts before starting a new one. But when I run this code, after the iterval, I get N number of API calls, for example if I typed 6 characters I get 6 API calls.
Why isn’t the above line clearTimeout(timeout);
clearing existing timeouts? I was only expecting the last one to fire.