React hooks 防抖

前阵子在打游戏,突然想起来前端貌似是有什么防抖、节流,就百度了一下,看了一眼没看懂,过了好久才又想起来,遂照着别人的代码码了一下。
参考:

  1. 经典防抖:人类高质量JS防抖与节流机制
  2. hooks防抖:React hooks 怎样做防抖?

因为我用的react hooks写的项目,看完经典防抖直接就去试了一下,发现不行,感觉是因为react hooks的特性引发的问题,又去找了一篇react hooks有关的知乎,二者结合了一下,成功。

核心debounce.js文件:

import {
    
     useCallback, useEffect, useRef } from "react"

function useDebounce(fn, delay, dep = []) {
    
    
	// useRef 可以跨周期保存数据,不会因重新渲染而被重置,这样定时器就有效了
	// 只有单击和连击的最后一次会生效
  const {
    
     current } = useRef({
    
     fn, time: null, firsttime: true })
  useEffect(function () {
    
    
    current.fn = fn
  }, [fn])

  return useCallback(function f(...args) {
    
    
    current.firsttime = !current.time
    if (current.firsttime) {
    
    
      // 依然没搞清楚为什么call 这里不call也能成功
      // current.fn.call(this, ...args)
      current.fn(...args)
    }
    if (current.time) {
    
    
      clearTimeout(current.time)
    }
    current.time = setTimeout(() => {
    
    
      current.time = null
      if (!current.firsttime) {
    
    
        // current.fn.call(this, ...args)
        current.fn(...args)
      }
    }, delay)
  }, dep)
}

export default useDebounce

应用:

import {
    
     login } from '../../service/services'
import Debounce from '../../utils/debounce.js'

function Login () {
    
    
  // success
  // 注意 这里Debounce必须处于顶层,也就是直接赋值给dologin常量,否则会违反react hooks 的规则 爆红
  const dologin = Debounce(() => {
    
    
    login(state).then(res => {
    
    
      if (res) {
    
    
        if (res.status === 200) {
    
    
          console.log('登陆成功!')
        } else {
    
    
          message.error(`${
      
      resp.msg}`)
        }
      }
    })
  }, 1000)
  return (
    <>
          <Button
            onClick={
    
    () => {
    
    
              dologin()
            }}
            }}
          >
            登录
          </Button>
    </>
  )
}

export default Login

为了方便阅读,我将不相关的其他代码都删掉了。

猜你喜欢

转载自blog.csdn.net/weixin_45543674/article/details/120114189