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)
    }
    // 如果不是第一次执行,那先清除上一个计时器
    if (current.time) {
      clearTimeout(current.time)
    }
    // 设置新的计时器
    current.time = setTimeout(() => {
   	  // 执行的第一部是设置计时器为null(也就是false,来控制current.firsttime)
      current.time = null
      // 如果不是第一次执行,那就执行
      if (!current.firsttime) {
        current.fn.call(this, ...args)
      }
    }, delay)
  }, dep) // 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

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值