参考资料:
https://blog.csdn.net/qq1361200/article/details/112253863
debounce防抖
普通实现
function debounce(fn, ms) {
let timer;
return function (...args) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn(...args)
timer = null;
}, ms);
}
}
react自定义hooks
每次组件重新渲染,都会执行一遍所有的hooks,这样debounce高阶函数里面的timer就不能起到缓存的作用(每次重渲染都被置空),timer不可靠,debounce的核心就被破坏了,所以需要useCallback缓存函数
import {useState, useEffect, useRef, useCallback} from 'react'
export 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)
}
vue3自定义hooks
import {
costomRef
} from 'vue'
export function debouncedRef(value, delay = 200) {
let timeout;
return costomRef((track, trigger) => {
return {
get() {
track()
return value
},
set(newValue) {
clearTimeout(timeout)
timeout = setTimeout(() => {
value = newValue;
trigger()
}, delay)
}
}
})
}
throttle节流
普通实现
function debounce(fn, ms) {
let flag = true;
return function (...args) {
if (flag) {
flag = false
let timer = setTimeout(()=>{
fn.apply(this,arguments)
flag = true
}, ms)
}
}
}
react自定义hooks
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);
}
vue3自定义hooks
import {
costomRef
} from 'vue'
export function throttleRef(value, delay = 200) {
let flag = true;
return costomRef((track, trigger) => {
return {
get() {
track()
return value
},
set(newValue) {
if (flag) {
flag = false
let timer = setTimeout(()=>{
value = newValue;
trigger()
flag = true
}, ms)
}
}
}
})
}