useDebounce 防抖

201 阅读2分钟

1. 基本概念--是什么?

原理:一个 dom 事件被触发时,会设定一个延迟处理时间,在这个时间内再次触发该事件,则会重新设定一个延迟处理时间。

2. 需求描述--有啥用?

场景某个文本输入框中的值发生改变,需要发起网络数据请求。

问题当用户每次向文本输入框输入值时,都会发起网络请求。那么用户在输入值时,大量的发起网络请求,给服务端造成了一定程度上的压力。

3. 需求分析--分析问题!

我们需要一个工具函数(或者hooks),这个工具函数(或者hooks)需要有以下几个功能:

参数含义默认值
value需要防抖的值-
wait时间周期,单位为毫秒500

综上所述,梳理思路如下:

首先 声明一个函数(或hooks)useDebunce。此函数接受需要防抖的值和自定义时间周期。

其次 使用定时器完成之间模拟时间周期。当事件触发后,如果之前的定时器存在则清除该定时器;否则声明一个定时器。

最后 声明响应式数据 debunceValue,当定时器的回调函数执行时,将防抖的值赋值给声明的响应式数据并将其作为该函数(或hooks)的返回值。

4. 手动实现--独立自主!

// hooks 核心函数
function useDebunce(...props) {
    let [value, wait = 500] = props
    // 定时器
    const timer = useRef(null)
    // 防抖的值
    const [debunceValue, setDebunceValue] = useState();

    // 上一个周期还在,则清空上个周期
    if (timer.current) {
        clearInterval(timer.current)
    }
    // 开始新的周期
    timer.current = setTimeout(() => {
        setDebunceValue(value)
        clearInterval(timer.current)
    }, wait)
    return debunceValue
}

// 测试
export default () => {
  const [value, setValue] = useState();
  const debouncedValue = useDebunce(value);

  return <>
    <input
      type="text"
      value={value}
      onChange={(e) => {
        setValue(e.target.value)
      }} />
    <p>输入框的值: {debouncedValue}</p>
  </>
}