之前有被问过,你如何实现让一个值成为节流的响应式的值
useThrottleState
- 使用
const [value, setValue] = useThrottleState(0, 1000)
- 实现
import { useEffect, useState, useRef } from "react";
function useThrottleState(initValue, delay = 200) {
const [, update] = useState({})
const value = useRef(null);
const timer = useRef(null);
useEffect(() => { value.current = initValue; }, [])
const throttle = (val) => {
value.current = val;
if (timer.current) {
return
}
timer.current = setTimeout(() => {
update({})
timer.current = null
}, delay)
}
const dispatch = (val) => {
console.log('dispatch', val);
throttle(val)
}
return [value.current, (val) => dispatch(val)]
}
export default useThrottleState
扩展:实现一个节流的Effect hook
useThrottleEffect
- 使用
const { cancel } = useThrottleEffect(() => {
console.log('useThrottleEffect执行');
}, 1000, [num])
- 实现
import { useEffect, useRef } from "react";
function useThrottleEffect(callback, delay = 200, deps) {
const timer = useRef(null)
useEffect(() => {
if (timer.current) return
timer.current = setTimeout(() => {
callback()
clearTimeout(timer.current)
timer.current = null;
}, delay)
}, deps)
/**
* @cancel 强行终止当前fn执行
*/
const cancel = () => {
clearTimeout(timeout.current)
timer.current = null
}
return { cancel }
}
export default useThrottleEffect