逃离闭包缺陷

众所周知,不会写BUG的不是好程序员(懂的都懂哈)

我说React比Vue难使没意见吧

想必大家肯定见过发送验证码的场景吧,他让你过一段时间才能重新发送

那我就写一下这个场景,来看看我的想法

  • 首先我整一个Login组件(我都是用 function component)
  • 然后我给他整一个状态 time
  • 当我点击发送验证码的时候,让 time 为60
  • 并且设置一个定时器,让 time 每过一秒减 1 ,当 time 等于 0 的时候 clear 定时器
  • perfect!!!

好的,接下来看代码实现(贴的是关键代码)

const [time, setTime] = useState(0)
const sendCode = () => {
    setTime(60)
    let timer: NodeJS.Timer
    timer = setInterval(() => {
      if (time === 0) {
        clearInterval(timer)
      }
      setTime(time - 1)
    }, 1000)
    //TODO
  }
  
<div className="flex">
  <input id='code' type={'text'} className="outline-none flex-1 text-lg" />
  <div onClick={() => { !time && sendCode() }}>{time ?  time + 's 后可重新发送' : '发送验证码'}</div>
</div>

下面来看一下结果

  • 点击发送之后,先是这个效果
    在这里插入图片描述
  • 一秒之后
    在这里插入图片描述
    我Interval呢???

这就是 hooks 的经典问题了,闭包缺陷

这里直接不说太深入
简单说就是 setTime 给 time 赋值会创建新的变量,相当于 setTime(60) 的确修改了 time ,在视图上也显示了,但是我定时器里面的 time 还是老的 time ,所以老的time是 0 一上来就给 timer 清除了,随后调用了 setTime(time - 1) ,实质上就是调用 setTIme(-1) ,所以随后你会看到的是 -1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值