自定义 倒计时的 Hooks

889 阅读2分钟

一、自定义 hooks 的项目初始化

  • npx create-react-app react-usecountdown
  • cd react-usecountdown
  • yarn start 或 npm start 或 npm run start
  • 在 src/components下,新建 TimeFun.jsuseCountDown.js image.png

二、开启自定义 hooks 之路

1.需求分析:

  1. 点击取验证码,开始倒计时
  2. 进入页面,不开启倒计时,点击才开启
  3. 倒计时开始途中,不能再次点击,要节流

image.png

2.在useCountDown.js中,书写我们的 倒计时 hook

// ◆导入 useState, useEffect, useRef  三个 Hooks
import { useState, useEffect, useRef } from 'react'

// ◆自定义一个 以 use 开头的函数:useCountDown (导出)
export const  = () => {
    // 1.定义倒计时初始值
    const [count, setCount] = useState(0)
    // 2.定义开启定时器的开关(节流优化,防止连续点击)
    const [flag, setFlag] = useState(true)
    // 3.设置文本显示
    const [timeText, setTimeText] = useState('获取验证码')
    // 4.定义计时器 的 ref 
    let timeIdRef = useRef(null)

    // ◆利用 useEffect 的副作用 return ()=>{} ,每次进来关闭定时器 
    useEffect(() => {
        return () => {
            clearInterval(timeIdRef.current)
        }
    }, [])

    // ◆利用 useEffect 的副作用检测定时器是否走完(watch)
    useEffect(() => {
        if (count <1) {
            // 1.定时器走完了,可以再次开启阀门
            setFlag(true)
            // 2.清除定时器
            clearInterval(timeIdRef.current)
            // 3.切换显示文本
            setTimeText('获取验证码')
        } else {
            // 4定时器没走完,显示文本
            setTimeText(count + 's之后获取验证码')
        }
    }, [count])

    // ◆开启定时器
    const start = (num = 10) => {  // num = 10 是默认值
        // 1.如果 flag 是 false 关闭阀门
        if (!flag) return
        // 2.不能再点击了
        setFlag(false)
        // 3.设置初始值
        setCount(num)
        // 4.开始倒计时
        timeIdRef.current = setInterval(() => {
            setCount((count) => count - 1)
        }, 1000)
    }
    // ◆返回值
    return { count, start, flag, timeText }
}

三、使用咱们自定义的 useCountDown hook

法1:自定义文本显示效果,不传值,使用默认值 10 秒

import React from 'react'
// 导入封装 的 计时器 hooks
import { useCountDown } from './useCountDown'
const TimeFun = () => {
    const { count, start, flag } = useCountDown()
    return <div>
        <button disabled={!flag} onClick={() => {
            start()
        }}>{flag ? '获取验证码' : count + 's之后获取验证码'}</button>
    </div>
}
export default TimeFun

法2:自定义文本显示效果,传任意值 ,比如 5 秒

import React from 'react'
// 导入封装 的 计时器 hooks
import { useCountDown } from './useCountDown'
const TimeFun = () => {
    const { count, start, flag } = useCountDown()
    return <div>
        <button disabled={!flag} onClick={() => {
            start(5)
        }}>{flag ? '获取验证码' : count + 's之后获取验证码'}</button>
    </div>
}
export default TimeFun

法3:使用默认文本显示效果

import React from 'react'
// 导入封装 的 计时器 hooks
import { useCountDown } from './useCountDown'
const TimeFun = () => {
    const { start, flag, timeText } = useCountDown()
    return <div>
        <button disabled={!flag} onClick={() => {
            start(30)
        }}>{timeText}</button>
    </div>
}
export default TimeFun