export function useDebounce<T extends (...args: Parameters<T>) => void>(
callback: T,
delay = 300,
dependencies: React.DependencyList = []
): (...args: Parameters<T>) => void {
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
useEffect(() => {
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, [dependencies]);
const debouncedCallback = useCallback(
(...args: Parameters<T>) => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
timeoutRef.current = setTimeout(() => {
callback(...args);
}, delay);
},
[callback, delay, ...dependencies]
);
return debouncedCallback;
}
I made a custom hook for debouncing in Next. When I was using this hook with mutate from useSWRImmutable, the problem was that the refetch was never occurring.
This is how I was using the hook
const handleMutate = useCallback(async () => {
await mutate();
}, [mutate]);
const debouncedMutate = useDebounce(handleMutate, 5000, [mutate]);
Then whenever I called debouncedMutate from anywhere the refetch call never occurred. I waited for a minute or more, then I even tried to change the time limit to 100ms but the call still did not occur.
export function useDebounceFunction<T extends (...args: unknown[]) => void>(
fn: T,
delay: number
) {
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
const fnRef = useRef(fn);
fnRef.current = fn;
return useCallback(
(...args: Parameters<T>): void => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
timeoutRef.current = setTimeout(() => {
fnRef.current(...args);
}, delay);
},
[delay]
);
}
Then when I started to use this custom hook, the issue was resolved, can anyone tell me why this was happening even though I was doing the same thing with useDebounce just using the useCallback outside the useDebounce hook?
I was using the useSWRImmutable inside a zustand store to fetch API and store the data in the store.
[dependencies].