使用Moment.js的React JS倒计时组件渲染空白问题求助
问题根因
- 返回值位置错误:
ShowTimer()函数的返回值写在了setInterval的异步回调内部,外层ShowTimer本身没有任何返回值,首次渲染时<span>内部实际是undefined,所以显示空白 - 未触发React重渲染:你直接修改
duration变量属于普通JS变量修改,React无法感知状态变更,不会触发组件重新渲染,就算倒计时数值变化了界面也不会更新 - 定时器逻辑缺陷:没有做定时器清理逻辑,组件重复渲染/卸载时会残留定时器,导致内存泄漏、计时异常
修复后的完整代码
// countdown.js import moment from 'moment'; import { useState, useEffect } from 'react'; const CountDownTimer = () => { // 用state存储倒计时显示文本,更新时触发重渲染 const [timeText, setTimeText] = useState(''); const eventTime = 1626573600; // 直接用数字类型避免隐式转换问题 useEffect(() => { // 计算初始剩余时间 const getLeftDuration = () => { const currentTime = Math.floor(Date.now() / 1000); const leftTime = eventTime - currentTime; return moment.duration(leftTime > 0 ? leftTime : 0, 'seconds'); }; let duration = getLeftDuration(); // 先更新一次初始值,避免首次渲染空白 const updateTimeText = () => { if (duration.asSeconds() <= 0) { setTimeText('活动已开始'); return false; } setTimeText(`${duration.days()} Days ${duration.hours()} Hours ${duration.minutes()} Minutes ${duration.seconds()} Seconds`); return true; }; updateTimeText(); // 创建定时器 const timer = setInterval(() => { duration = moment.duration(duration.asSeconds() - 1, 'seconds'); const hasLeft = updateTimeText(); // 倒计时结束清除定时器 if (!hasLeft) clearInterval(timer); }, 1000); // 组件卸载时清除定时器,避免内存泄漏 return () => clearInterval(timer); }, []); // 空依赖数组保证仅组件挂载时执行一次 return <span>{timeText}</span> } export default CountDownTimer;
额外说明
- 原有调用方式不需要修改,直接按你之前的写法引入使用即可
- 如果需要修改目标活动时间,直接调整
eventTime的时间戳值即可 - Moment.js目前已经停止维护,如果你是新项目可以考虑用dayjs等更轻量的时间库替代,API基本兼容
内容的提问来源于stack exchange,提问作者bagofmilk
相关产品推荐
相关产品推荐

