React中实现防抖功能的两种方式
问题这有一个简单的防抖函数,短时间内多次触发同一事件,只执行最后一次function debounce (fn, wait) {let timer = nullreturn function (...args) {if (timer !== null) {clearTimeout(timer)}timer = setTimeout(() => {fn(args)timer = null},
·
问题
这有一个简单的防抖函数,短时间内多次触发同一事件,只执行最后一次
function debounce (fn, wait) {
let timer = null
return function (...args) {
if (timer !== null) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn(args)
timer = null
}, wait)
}
}
但问题是这个函数在react中使用不生效
export default () => {
const handleClick = debounce(() => console.log("click fast!"), 1000));
return (
<button onClick={handleClick}>click fast!</button>
);
};
原因就是函数式组件每次渲染,函数都会被重建,导致平时用的 debounce 函数中的timer会重新创建,进而导致防抖失效。
方案一
使用useRef
来缓存timer
变量
export default function () {
const click = useDebounce((e: Event) => {
console.log(e);
}, 1000)
return (
<button onClick={click}>按钮</button>
);
}
function useDebounce(fn: Function, delay: number) {
const refTimer = useRef<number>();
return function f(...args: any) {
if (refTimer.current) {
clearTimeout(refTimer.current);
}
refTimer.current = setTimeout(() => {
fn(args);
}, delay);
}
}
方案二
使用useCallback
来缓存函数,只要第二个参数传空数组,那么在组件重新选然时,useCallback中的函数就不会重新创建
export default function DeBounce() {
const click = useCallback(clickInner(), []);
function clickInner() {
let timer: number;
return function (e: Event) {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
console.log(e);
}, 1000);
}
}
return (
<button onClick={click}>按钮</button>
);
}
更多推荐
已为社区贡献1条内容
所有评论(0)