You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Day.js实现10分钟倒计时,结束后将isValid从true改为false

问题解决方法

核心问题说明

原有代码的问题如下:

  • 直接将系统当前时间的分、秒赋值给展示状态,没有计算10分钟后目标时间与当前时间的差值,无法实现倒计数效果
  • 时间计算逻辑冗余,Day.js内置了diff方法可以直接计算两个时间点的毫秒差,不需要手动拆分时分秒做减法
  • 缺少倒计时结束的判断逻辑,无法触发isValid的状态修改

修复后完整代码

import { useState, useEffect } from 'react';
import dayjs from 'dayjs';

// 假设setIsValid是你传入的状态修改函数,可从props/上下文等位置获取
const CountdownTimer = ({ setIsValid }) => {
  const [minutes, setMinutes] = useState(0);
  const [seconds, setSeconds] = useState(0);
  const tokenTTL = 10; // 倒计时总时长,单位:分钟

  useEffect(() => {
    // 仅在组件挂载时计算一次目标时间,避免时间漂移
    const targetTime = dayjs().add(tokenTTL, 'minute');
    const interval = setInterval(() => {
      const currentTime = dayjs();
      // 计算当前时间和目标时间的差值,单位:毫秒
      const diffMs = targetTime.diff(currentTime);
      
      // 差值小于等于0说明倒计时结束
      if (diffMs <= 0) {
        clearInterval(interval);
        setMinutes(0);
        setSeconds(0);
        setIsValid(false);
        return;
      }

      // 将差值转换为剩余的分、秒
      const remainMin = Math.floor(diffMs / 1000 / 60);
      const remainSec = Math.floor((diffMs / 1000) % 60);
      setMinutes(remainMin);
      setSeconds(remainSec);
    }, 1000);

    // 组件卸载时清除定时器,避免内存泄漏
    return () => clearInterval(interval);
  }, [setIsValid]);

  // 补0格式化,保证展示为两位数字
  const formatTimeNum = (num) => num < 10 ? `0${num}` : num;

  return (
    <p className="Timer">
      <span className="minutes">{formatTimeNum(minutes)}</span>
      <span className="divider">:</span>
      <span className="seconds">{formatTimeNum(seconds)}</span>
    </p>
  );
};

export default CountdownTimer;

逻辑说明

  • 目标时间仅在组件首次挂载时计算,保证倒计时总时长固定为10分钟
  • 用Day.js原生的diff方法计算时间差,避免手动计算出现的时区、进位误差
  • 每次定时器触发优先判断倒计时是否结束,符合条件立即终止定时器并修改isValid状态
  • 增加补0格式化逻辑,符合通用计时器的展示规范

内容的提问来源于stack exchange,提问作者shivetay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 01:09:01