最近给hooks内的组件添加防抖发现之前的防抖函数不生效了,明明在规定时间内点击,居然会执行两遍。这是原来的防抖代码。
export function debounce(func: any, wait: number = 800, immediate = false) {
let timer: any = '';
return function (...args: any[]) {
const _this = this;
const _arguments = arguments;
let res;
if (timer) clearTimeout(timer);
if (immediate) {
let nowDo = !timer;
timer = setTimeout(function () {
timer = null;
}, wait);
if (nowDo) res = func.call(_this, ..._arguments);
} else {
timer = setTimeout(function () {
res = func.call(_this, ..._arguments);
}, wait);
}
return res;
};
}
经过调试发现是由于hooks的更新机制导致的,每次界面更新,防抖函数就会从新绑定,内部的 timer
自然就会被重置。
所以我又搞了个 hooks 内使用的防抖,代码在下面。不得不吐槽一句,hooks 感觉好繁琐啊。
export function useDebounce(fn, delay, immediate, dep = []) {
const { current } = useRef({ fn, timer: null });
useEffect(
function () {
current.fn = fn;
},
[fn]
);
return useCallback(function f(...args) {
if (current.timer) {
clearTimeout(current.timer);
}
let res;
if (immediate) {
let nowDo = !current.timer;
current.timer = setTimeout(() => {
current.timer = null;
}, delay);
if (nowDo) res = current.fn.call(this, ...args);
} else {
current.timer = setTimeout(() => {
res = current.fn.call(this, ...args);
}, delay);
}
return res;
}, dep);
}
网友评论