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; }
Früher habe ich useDebounce
Haken hergestellt und verwendet.
Es gibt jedoch einige Probleme bei der Verwendung von useDebounce
in Größenänderungsereignissen.
useDebounce hook
Muss auf der Komponente ausgeführt werden, da sie useEffect intern verwendet.
Die Größenänderungsfunktion ist jedoch so eingerichtet, dass sie auf useEffect ausgeführt wird, wie unten gezeigt.
Außerdem verwendet der obige Code den Wert als Faktor, aber ich denke, wir müssen ihn als Rückruf erhalten, um den folgenden Code verwenden zu können.
useEffect(() => { const handler = () => { if (liRef.current) setWidth(liRef.current.clientWidth); }; window.addEventListener('resize', handler); return () => window.removeEventListener('resize', handler); }, []);
Wie verwende ich den obigen Code, um das vorhandene useDebounce zu nutzen?
如果你直接在React组件中使用debounced函数,它将不起作用,因为每个渲染都会创建一个新函数,相反,你可以使用这个
useDebounce
钩子:useRef
确保它与上次提供的函数相同,并且useLayoutEffect
确保在每次渲染时,对函数的引用都会更新。有关这方面的更多信息,请参阅“最新参考”模式反应
我认为与其通过
useEffect
实现去抖,不如将去抖逻辑实现为一个函数。useEffect
当deps
引用的状态改变时执行。也就是说,由于是一个如果只按照执行流程就容易漏掉的逻辑,所以后期维护时很难弄清楚这个useEffect
是从哪一个流程衍生出来的,调试起来也比较困难。示例
自定义反跳
如果您使用
lodash
,则只需导入即可使用它。Lodash Debounce
希望这有帮助:)