倒计时器

渲染一个倒计时器,在倒计时到达零时打印一条消息。

  • 使用 useState() 钩子创建一个状态变量来保存时间值。从 props 中进行初始化,并将其解构为各个组件。
  • 使用 useState() 钩子创建 pausedover 状态变量,用于在暂停或时间已经用完时阻止计时器的运行。
  • 创建一个 tick 方法,根据当前值更新时间值(即将时间减少一秒)。
  • 创建一个 reset 方法,将所有状态变量重置为初始状态。
  • 使用 useEffect() 钩子通过 setInterval() 每秒调用 tick 方法,并在组件卸载时使用 clearInterval() 进行清理。
  • 使用 String.prototype.padStart() 将时间数组的每个部分填充为两个字符,以创建计时器的可视化表示。
const CountDown = ({ hours = 0, minutes = 0, seconds = 0 }) => {
  const [paused, setPaused] = React.useState(false);
  const [over, setOver] = React.useState(false);
  const [[h, m, s], setTime] = React.useState([hours, minutes, seconds]);

  const tick = () => {
    if (paused || over) return;
    if (h === 0 && m === 0 && s === 0) setOver(true);
    else if (m === 0 && s === 0) {
      setTime([h - 1, 59, 59]);
    } else if (s == 0) {
      setTime([h, m - 1, 59]);
    } else {
      setTime([h, m, s - 1]);
    }
  };

  const reset = () => {
    setTime([parseInt(hours), parseInt(minutes), parseInt(seconds)]);
    setPaused(false);
    setOver(false);
  };

  React.useEffect(() => {
    const timerID = setInterval(() => tick(), 1000);
    return () => clearInterval(timerID);
  });

  return (
    <div>
      <p>{`${h.toString().padStart(2, '0')}:${m
        .toString()
        .padStart(2, '0')}:${s.toString().padStart(2, '0')}`}</p>
      <div>{over ? "时间到了!" : ''}</div>
      <button onClick={() => setPaused(!paused)}>
        {paused ? '继续' : '暂停'}
      </button>
      <button onClick={() => reset()}>重新开始</button>
    </div>
  );
};

ReactDOM.createRoot(document.getElementById('root')).render(
  <CountDown hours={1} minutes={45} />
);