得物、拼多多经常考,倒计时组件1.倒计时组件2.如何实现精确计时(setInterval 1s先就update以前知道写但没考虑到为什么,时间戳同步)// Countdown.jsximport React, { useEffect, useState, useRef } from 'react';/*** props:* - endAt: number (timestamp ms) 或 Date* - onFinish?: () =&gt; void* - tickMs?: number (minimal tick granularity, default 1000)*/export default function Countdown({ endAt, onFinish, tickMs = 1000 }) {const endTs = typeof endAt === 'number' ? endAt : endAt.getTime();const [remaining, setRemaining] = useState(Math.max(0, endTs - Date.now()));const mounted = useRef(true);useEffect(() =&gt; {mounted.current = true;// initial syncfunction update() {const now = Date.now();const rem = Math.max(0, endTs - now);if (!mounted.current) return;setRemaining(rem);if (rem === 0) {onFinish?.();return;}// Align next update to wall-clock second boundary (or tickMs)const delay = Math.min(tickMs,1000 - (now % 1000) // align to next second for nicer UX);// If &lt;1s left, use requestAnimationFrame for smoothnessif (rem &lt;= 1000) {requestAnimationFrame(update);} else {setTimeout(update, delay);}}update();return () =&gt; {mounted.current = false;};}, [endTs, onFinish, tickMs]);const sec = Math.ceil(remaining / 1000);const mm = Math.floor(sec / 60);const ss = sec % 60;return (<div>{mm}:{String(ss).padStart(2, '0')}</div>);}