Files
mnote/src/hooks/use-debounced-callback.ts
T

42 lines
1.0 KiB
TypeScript

"use client";
import { useEffect, useMemo, useRef } from "react";
type Procedure<T extends unknown[]> = (...args: T) => void;
type DebouncedProcedure<T extends unknown[]> = Procedure<T> & { cancel: () => void };
/**
* 用于本地输入的防抖工具,默认等待 800ms 再触发回调。
*/
export const useDebouncedCallback = <T extends unknown[]>(
callback: Procedure<T>,
delay: number,
): DebouncedProcedure<T> => {
const timerRef = useRef<NodeJS.Timeout | null>(null);
const callbackRef = useRef(callback);
useEffect(() => {
callbackRef.current = callback;
}, [callback]);
return useMemo(() => {
const debounced = ((...args: T) => {
if (timerRef.current) {
clearTimeout(timerRef.current);
}
timerRef.current = setTimeout(() => {
callbackRef.current(...args);
}, delay);
}) as DebouncedProcedure<T>;
debounced.cancel = () => {
if (timerRef.current) {
clearTimeout(timerRef.current);
timerRef.current = null;
}
};
return debounced;
}, [delay]);
};