useCountDown (React Hooks)倒计时

javascript 复制代码
import { useState, useRef } from "react";
import "./styles.css";

/**********************************************************
 * 补全 useCountDown (React Hooks)倒计时的功能
 **********************************************************/

// 请补全,返回:
// count     当前剩余秒数
// start()   开始
// reset()   重置
// isRunning 是否在运行
function useCountDown(options) {
  const {
    total, // 总秒数
    onEnd, // 倒计时结束回调
  } = options;

  const [count, setCount] = useState(total);
  const countRef = useRef(total);

  const [isRunning, setIsRunning] = useState(false);

  const start = () => {
    reset();
    const updateCount = () => {
      if (countRef.current <= 0) {
        setIsRunning(false);
        onEnd();
        clearInterval(timer);
        return;
      }

      setIsRunning(true);
      setCount((count) => count - 1);
      countRef.current--;
    };

    updateCount();
    const timer = setInterval(() => {
      updateCount();
    }, 1000);
  };

  const reset = () => {
    setCount(total);
    countRef.current = total;
  };

  return {
    count,
    start,
    isRunning,
  };
}

// 使用示例
function SmsButton() {
  const { count, start, isRunning } = useCountDown({
    total: 6,
    onEnd: () => console.log("可以重新发送了"),
  });

  return (
    <button disabled={isRunning} onClick={start}>
      {isRunning ? `${count}s 后重试` : "发送验证码"}
    </button>
  );
}

export default function App() {
  return (
    <div className="App">
      <SmsButton />
    </div>
  );
}

演示:

倒计时发送验证码

注意点

  1. 闭包问题,需要使用setCount((count) => count - 1);函数式更新状态,使用ref获取最新count
  2. 计时器需要清理,避免内存泄漏
相关推荐
每天吃饭的羊几秒前
水平,垂直居中
前端·javascript·html
倾颜5 分钟前
React 19 源码怎么读:createRoot 和 root.render 到底做了什么?
react.js
鼎道开发者联盟23 分钟前
鼎享会 | OpenClaw Control UI 前端架构全解析:自研 UI 对接 Server 实操指南
前端·ui·架构·openclaw·control ui
尘世中一位迷途小书童25 分钟前
一套完整的给予ceium封装的组件库,可满足企业级开发
前端
Z_Wonderful26 分钟前
微前端:Webpack 配置 vs Vite 配置 超清晰对比
前端·webpack·node.js
thankseveryday28 分钟前
Three.js 把 Blender 绘制的曲线(Bezier / 曲线) 导入 Three.js 并作为运动路径 / 动画路径使用
开发语言·javascript·blender
码云数智-园园31 分钟前
HTTPS是如何工作的?从HTTP到HTTPS的加密演进
前端
隔窗听雨眠39 分钟前
HTML头部元信息避坑指南
前端·html
Gauss松鼠会1 小时前
【openGauss】openGauss 磁盘引擎之 ustore
java·服务器·开发语言·前端·数据库·经验分享·gaussdb
LIO1 小时前
前端响应式页面开发全攻略:核心技术 + 实现效果 + 实战指南
前端·响应式设计