倒计时组件应通过 props 接收目标时间戳,结合自定义 hook usecountdown 封装逻辑,返回剩余时间、完成状态与重置方法;支持暂停、动态重置及灵活格式化,避免硬编码与 ui 耦合。

用 Props 传入目标时间,让组件自主计算剩余秒数
倒计时组件的核心是“目标时间”与“当前时间”的差值。不要在子组件里硬编码结束时间,而是通过 Props 接收一个时间戳(如 Date.now() + 60000),组件内部用 useEffect 和 setInterval 实时更新剩余毫秒数。这样同一组件可复用于登录验证码、订单锁定、活动倒计时等场景,只需改传不同的 endTime。
把倒计时逻辑抽成自定义 Hook,避免重复写定时器
将倒计时状态和控制逻辑封装为 useCountdown(endTime):它返回 [remaining, isFinished, reset]。组件只负责接收 endTime 并调用该 Hook,无需关心 clearInterval、依赖数组或时间格式化。例如:
-
endTime变化时自动重置倒计时(适合动态刷新的截止时间) - Hook 内部处理
remaining 后自动清理定时器并设 <code>isFinished = true - 组件内只需
{isFinished ? '已结束' : formatSeconds(remaining)}
父组件控制启停与重置,实现状态下发与反向通信
倒计时常需外部干预——比如用户点击“重新发送”,或表单提交成功后暂停。这时不能只靠 Props 单向传递时间,还需通过回调函数实现“子传父”:
- 父组件传入
onFinish={() => handleResend()},子组件倒计时归零时触发 - 传入
isPausedProp 控制是否暂停定时器(比 unmount 更轻量) - 提供
reset方法(来自自定义 Hook)给父组件调用,实现按钮一键重置
格式化显示要灵活,别在组件里写死“分:秒”
不同场景对时间展示要求不同:验证码常用“XX 秒后重发”,活动页可能需要“D 天 H 小时 M 分钟”。建议把格式化逻辑交给父组件或通过 Prop 传入渲染函数:
- 接收
renderContent={(ms) => `${Math.floor(ms / 1000)}s`} - 或传入
format="mm:ss",组件内部按规则解析并格式化(支持 h:mm:ss、d天h小时等) - 避免在倒计时组件里耦合 UI 样式或文案,保持职责单一










