import { useEffect, useState } from 'react';
export default function useDebounce(text: string, delay: number) {
const [value, setValue] = useState('');
useEffect(() => {
const timerId = setTimeout(() => {
setValue(text);
}, delay);
return () => {
clearTimeout(timerId);
};
}, [text, delay]);
return value;
}
我曾经制作和使用 useDebounce 钩子。
但是,在调整大小事件中使用 useDebounce 存在一些问题。
useDebounce hook 必须在组件顶部运行,因为它在内部使用了 useEffect。
但是,调整大小函数设置为在 useEffect 上运行,如下所示。
此外,上面的代码将值作为一个因素,但我认为我们需要接收它作为回调才能使用下面的代码。
useEffect(() => {
const handler = () => {
if (liRef.current) setWidth(liRef.current.clientWidth);
};
window.addEventListener('resize', handler);
return () => window.removeEventListener('resize', handler);
}, []);
如何使用上面的代码来利用现有的useDebounce?
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
如果你直接在React组件中使用debounced函数,它将不起作用,因为每个渲染都会创建一个新函数,相反,你可以使用这个
useDebounce钩子:function useDebounce(callback, delay) { const callbackRef = React.useRef(callback) React.useLayoutEffect(() => { callbackRef.current = callback }) return React.useMemo( () => debounce((...args) => callbackRef.current(...args), delay), [delay], ) }useRef确保它与上次提供的函数相同,并且useLayoutEffect确保在每次渲染时,对函数的引用都会更新。有关这方面的更多信息,请参阅“最新参考”模式反应
我认为与其通过
useEffect实现去抖,不如将去抖逻辑实现为一个函数。useEffect当deps引用的状态改变时执行。也就是说,由于是一个如果只按照执行流程就容易漏掉的逻辑,所以后期维护时很难弄清楚这个useEffect是从哪一个流程衍生出来的,调试起来也比较困难。示例
自定义反跳function debounce(func, timeout = 300) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => { func.apply(this, args); }, timeout); }; }function saveInput() { console.log('Saving data'); } const processChange = debounce(() => saveInput());如果您使用
lodash,则只需导入即可使用它。Lodash Debounceimport { debounce } from 'lodash';const debounceOnChange = debounce(() => { console.log("This is a debounce function"); }, 500);希望这有帮助:)