防抖:觸發(fā)高頻事件后n秒內(nèi)函數(shù)只會(huì)執(zhí)行一次,如果n秒內(nèi)高頻事件再次被觸發(fā),則重新計(jì)算時(shí)間。
function useDebounce(fn, delay, dep = []) {
const { current } = useRef({ fn, timer: null });
useEffect(function () {
current.fn = fn;
}, [fn]);
return useCallback(function f(...args) {
if (current.timer) {
clearTimeout(current.timer);
}
current.timer = setTimeout(() => {
current.fn.call(this, ...args);
}, delay);
}, dep)
}
節(jié)流:高頻事件觸發(fā),但在n秒內(nèi)只會(huì)執(zhí)行一次,所以節(jié)流會(huì)稀釋函數(shù)的執(zhí)行頻率。
function useThrottle(fn, delay, dep = []) {
const { current } = useRef({ fn, timer: null });
useEffect(function () {
current.fn = fn;
}, [fn]);
return useCallback(function f(...args) {
if (!current.timer) {
current.timer = setTimeout(() => {
delete current.timer;
}, delay);
current.fn.call(this, ...args);
}
}, dep);
}
備注:createRef 每次渲染都會(huì)返回一個(gè)新的引用,而 useRef 每次都會(huì)返回相同的引用。
每次組件重新渲染,都會(huì)執(zhí)行一遍所有的hooks,這樣debounce高階函數(shù)里面的timer就不能起到緩存的作用(每次重渲染都被置空)。timer不可靠,debounce的核心就被破壞了。使用useRef的目的就是為了解決這個(gè)問題。
useRef實(shí)現(xiàn)了React組件的緩存機(jī)制。