You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
1.8 KiB
82 lines
1.8 KiB
/** |
|
* 防抖 Hook |
|
* 使用 lodash-es 的 debounce 函数 |
|
*/ |
|
import React, { useEffect, useMemo, useRef } from 'react'; |
|
import { debounce } from 'lodash-es'; |
|
|
|
/** |
|
* 防抖值 Hook |
|
* @param value 需要防抖的值 |
|
* @param delay 延迟时间(毫秒) |
|
* @returns 防抖后的值 |
|
*/ |
|
export function useDebounceValue<T>(value: T, delay: number = 300): T { |
|
const [debouncedValue, setDebouncedValue] = React.useState<T>(value); |
|
|
|
useEffect(() => { |
|
const handler = setTimeout(() => { |
|
setDebouncedValue(value); |
|
}, delay); |
|
|
|
return () => { |
|
clearTimeout(handler); |
|
}; |
|
}, [value, delay]); |
|
|
|
return debouncedValue; |
|
} |
|
|
|
/** |
|
* 防抖函数 Hook |
|
* @param callback 需要防抖的函数 |
|
* @param delay 延迟时间(毫秒) |
|
* @returns 防抖后的函数 |
|
*/ |
|
export function useDebounce<T extends (...args: any[]) => any>( |
|
callback: T, |
|
delay: number = 300 |
|
): T { |
|
const callbackRef = useRef(callback); |
|
|
|
// 更新 callback ref |
|
useEffect(() => { |
|
callbackRef.current = callback; |
|
}, [callback]); |
|
|
|
// 创建防抖函数 |
|
const debouncedCallback = useMemo(() => { |
|
const func = (...args: Parameters<T>) => { |
|
callbackRef.current(...args); |
|
}; |
|
|
|
return debounce(func, delay); |
|
}, [delay]); |
|
|
|
// 清理 |
|
useEffect(() => { |
|
return () => { |
|
debouncedCallback.cancel(); |
|
}; |
|
}, [debouncedCallback]); |
|
|
|
return debouncedCallback as T; |
|
} |
|
|
|
/** |
|
* 使用示例: |
|
* |
|
* // 防抖值 |
|
* const [searchText, setSearchText] = useState(''); |
|
* const debouncedSearchText = useDebounceValue(searchText, 500); |
|
* |
|
* useEffect(() => { |
|
* // 使用防抖后的值进行搜索 |
|
* search(debouncedSearchText); |
|
* }, [debouncedSearchText]); |
|
* |
|
* // 防抖函数 |
|
* const handleSearch = useDebounce((text: string) => { |
|
* console.log('Searching:', text); |
|
* }, 500); |
|
*/
|
|
|