'use client' import { useState, useEffect, useCallback, useRef } from 'react' /** * 防抖值 Hook * @param value 需要防抖的值 * @param delay 延迟时间(毫秒) * @returns 防抖后的值 */ export function useDebounce(value: T, delay: number): T { const [debouncedValue, setDebouncedValue] = useState(value) useEffect(() => { const timer = setTimeout(() => { setDebouncedValue(value) }, delay) return () => { clearTimeout(timer) } }, [value, delay]) return debouncedValue } /** * 防抖回调 Hook * @param callback 需要防抖的回调函数 * @param delay 延迟时间(毫秒) * @returns 防抖后的回调函数 */ export function useDebouncedCallback any>( callback: T, delay: number ): (...args: Parameters) => void { const timeoutRef = useRef(null) const callbackRef = useRef(callback) // 保持回调函数的最新引用 useEffect(() => { callbackRef.current = callback }, [callback]) // 清理定时器 useEffect(() => { return () => { if (timeoutRef.current) { clearTimeout(timeoutRef.current) } } }, []) return useCallback((...args: Parameters) => { if (timeoutRef.current) { clearTimeout(timeoutRef.current) } timeoutRef.current = setTimeout(() => { callbackRef.current(...args) }, delay) }, [delay]) } /** * 节流回调 Hook * @param callback 需要节流的回调函数 * @param delay 延迟时间(毫秒) * @returns 节流后的回调函数 */ export function useThrottledCallback any>( callback: T, delay: number ): (...args: Parameters) => void { const lastRunRef = useRef(0) const timeoutRef = useRef(null) const callbackRef = useRef(callback) // 保持回调函数的最新引用 useEffect(() => { callbackRef.current = callback }, [callback]) // 清理定时器 useEffect(() => { return () => { if (timeoutRef.current) { clearTimeout(timeoutRef.current) } } }, []) return useCallback((...args: Parameters) => { const now = Date.now() const timeSinceLastRun = now - lastRunRef.current if (timeSinceLastRun >= delay) { lastRunRef.current = now callbackRef.current(...args) } else { // 如果在节流期间,设置一个定时器在节流期结束后执行 if (timeoutRef.current) { clearTimeout(timeoutRef.current) } timeoutRef.current = setTimeout(() => { lastRunRef.current = Date.now() callbackRef.current(...args) }, delay - timeSinceLastRun) } }, [delay]) }