在React+TS中使用自定义Hook(验证码倒计时)

1,792 阅读2分钟

前言

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

那么什么是Hooks?

Hook 是一些可以让你在函数组件里“钩入” React state 及生命周期等特性的函数。Hook 不能在 class 组件中使用 —— 这使得你不使用 class 也能使用 React。

React 内置了一些像 useState 这样的 Hook。你也可以创建你自己的 Hook 来复用不同组件之间的状态逻辑。这篇文章就来介绍一下自定义Hook

自定义Hook

自定义 Hooks 针对不同组件实现不同状态逻辑复用

  • 自定义 Hooks 是一个函数,约定函数名称必须以 use 开头,React 就是通过函数名称是否以 use 开头来判断是不是 Hooks
  • Hooks 只能在函数组件中或其他自定义 Hooks 中使用,否则,会报错!
  • 自定义 Hooks 用来提取组件的状态逻辑,根据不同功能可以有不同的参数和返回值(就像使用普通函数一样)

场景: 倒计时-验证码

核心代码:

import { useEffect, useRef, useState } from 'react'
 // callback 是结束之后要执行什么事情
export default function useCountDown (initCount = 10, callBack = () => {}) { 
 // 泛型
  const timeId = useRef<{id:number}>({ id: -1 })
  const [count, setCount] = useState(initCount)

  const start = () => {
    setCount(initCount)
    // setInterval 在node 和 浏览器都有,所以要指定
    timeId.current.id = window.setInterval(() => {
      setCount((count) => count - 1)
    }, 1000)
  }
  useEffect(() => {
    // 清除副作用
    return () => {
      clearInterval(timeId.current.id)
    }
  }, [])

  useEffect(
    () => {
      // console.log(count, timeId.current)
      // 当倒计时为0时 清除定时器
      if (count === 0) {
        clearInterval(timeId.current.id)
        callBack()
      }
    },
    [count]   // 监听 count
  )

  return { count, start }
}

完整功能:

 import useCountDown from '@/hooks/useCountDown' // 引入Hook
 
const Login = () => {
// 发送验证码
 // 设置初始值  定时器结束时候可以继续点击
const { count, start } = useCountDown(10, () => setSendAble(true))
// 默认刚开始可以点击
const [sendAble, setSendAble] = useState(true)
const  onSendCode=()=>{
// 开启定时器
start()
// 关闭
setSendAble(false)
}

return  <button className="code-extra" onClick={onSendCode}>{ sendAble ? '发送验证码' : count + '秒之后发送'}</button>
}