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

ReactJS中基于Countdown Timer的If条件判断不生效问题

问题根因

你的条件判断失效是写法违背React基本运行逻辑导致的,具体问题:

  1. 原Countdown函数无返回值,组件外层初始化拿到的distance是undefined,定时器内部更新的distance是函数局部变量,Home组件完全无法感知值的变化,自然不会触发重渲染更新按钮状态
  2. 直接用document.getElementById操作DOM的写法和React状态驱动视图的机制冲突,倒计时更新时不会同步刷新组件内的判断逻辑
  3. 原逻辑没有做定时器清理,组件卸载后定时器仍会运行,存在内存泄漏问题
  4. JSX里混用了class和className属性,会触发控制台警告,React中元素类名必须统一用className声明

修复方案

把倒计时逻辑改写成React自定义Hook,通过状态管理倒计时值,组件可以实时拿到最新的剩余时间触发重渲染。

第一步:重写Countdown.js为自定义Hook

import { useState, useEffect } from 'react';

function useCountdown(targetDate) {
  // 初始化时计算首次剩余时间差
  const [distance, setDistance] = useState(() => new Date(targetDate).getTime() - Date.now());

  useEffect(() => {
    const timer = setInterval(() => {
      const leftTime = new Date(targetDate).getTime() - Date.now();
      setDistance(leftTime);
      // 倒计时归0时清除定时器
      if (leftTime < 0) clearInterval(timer);
    }, 1000);

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

  // 计算格式化展示时间
  const days = Math.floor(distance / (1000 * 60 * 60 * 24));
  const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
  const seconds = Math.floor((distance % (1000 * 60)) / 1000);

  const displayText = distance < 0 
    ? "Mint is Live!" 
    : `${days}d ${hours}h ${minutes}m ${seconds}s`;

  return { distance, displayText };
}

export default useCountdown;

第二步:修改Home页面调用逻辑

移除组件外的无效调用,在组件内部引入Hook拿到实时状态,直接通过状态渲染视图,删除原生DOM操作代码:

import React from 'react';
import '../../App.css';
import useCountdown from '../Countdown';

function Home() {
  // 传入目标倒计时时间,获取实时剩余时间和展示文本
  const { distance, displayText } = useCountdown("Jun 27, 2022 22:27:10");

  return (
    <>
    <div className="App">
        <div>
          <div className='hero-container'>
            <div className="courses-container">
              <div className="course">
                <div className="course-preview">
                    <h6>Welcome</h6>
                    <h2>PROJECT NAME</h2>
                </div>
                <div className="course-info">
                    <div className="progress-container">
                        <span className="progress-text">/1000</span>
                    </div>
                    {/* 直接渲染状态中的倒计时文本 */}
                    <h2 id="demo">{displayText}</h2>
                    <div id='input-number' className='input-number-location'>
                      <input className='input-number button' type="number" name="amount" defaultValue="1" min="1" max="20"/>
                    </div>
                    {/* 状态实时更新,条件判断会正常触发重渲染切换按钮 */}
                    {distance < 0 
                      ? <button className="btncard">OPEN</button> 
                      : <button className="btncard">APP CLOSED</button>
                    }
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

export default Home;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:21:22