React+Hooks+moment实现倒计时

1,211 阅读1分钟

记录一下react 实现倒计时的一个小demo

问题背景:

需要从服务器端获取一个时间作为倒计时结束的时间,根据与当前的时间差,生成倒计时所需要的秒数。 比如:当前时间为23:55分,服务器获取到的时间为00:00,那么时间差就是 00:05:00

实现思路:

用倒计时结束时间减去当前时间,得到倒计时的秒数,利用setInterval每秒将倒计时秒数减1,直到倒计时秒数为0时,清除定时器,页面销毁时,清除副作用。

<body>
  <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  <script src="https://cdn.bootcss.com/moment.js/2.20.1/moment.min.js"></script>

  <div id="app"></div>

  <script type="text/babel">
    const { useState, useEffect, useRef } = React;

    let timer = null;

    function App() {
      //react Hooks

      // 当前时间
      const [currentTime, setCurrentTime] = useState(moment());
      // 终止时间
      const [endTime, setEndTime] = useState(moment().add(15, "m"));

      // 时间差 /倒计时时间
      const [diffTime, setDiffTime] = useState(endTime.diff(currentTime, "s"));

      // const timer = useRef();

      // console.log("timer", timer);
      useEffect(() => {
        // 开启定时器

        if (diffTime == 0) {
          window.clearInterval(timer);
          console.log("清除定时器");
        }

        if (timer) return;
        timer = window.setInterval(() => {
          setDiffTime((diffTime) => diffTime - 1);
        }, 1000);
      }, [diffTime]);

      useEffect(() => {
        // 清除副作用
        return () => {
          clearInterval(timer);
        };
      }, []);

      // 将秒转成时分秒
      function convertSecToHHmmss(sec) {
        let currentSec = moment.duration(sec, "seconds");
        return moment({
          h: currentSec.hours(),
          m: currentSec.minutes(),
          s: currentSec.seconds(),  
        }).format("HH:mm:ss");
      }

      return (
        <div>
          <div>当前时间:{currentTime.format("YYYY-MM-DD HH:mm:ss")} </div>
          <div>倒计时结束时间: {endTime.format("YYYY-MM-DD HH:mm:ss")}</div>
          <div>倒计时:{convertSecToHHmmss(diffTime)}</div>
        </div>
      );
    }

    ReactDOM.render(<App />, document.getElementById("app"));
  </script>
</body>

实现效果

微信图片_20220426230826.png