countDown+react+hook

道阻且长,行而不辍,未来可期

知识点一:
new Date().getTime()可以得到得到1970年01月1日0点零分以来的毫秒数。单位是毫秒

scala 复制代码
 new Date().getTime()/1000获取秒数

  1分钟60秒,1小时60分钟
  1hour:60*60=>单位是秒   60*60*1000=>单位是秒
  1day:24*60*60=>单位是秒  24*60*60*1000=>单位是秒

知识点二、
为什么使用 requestAnimationFrame 来写定时器呢?

答:当页面离开或切换到其他标签页时,requestAnimationFrame 中的代码将不再执行。

详解:因为 requestAnimationFrame 方法依赖于浏览器的渲染循环,而在页面不可见或失去焦点时,浏览器会暂停渲染循环以减少资源消耗。 因此,使用 requestAnimationFrame 实现的动画或定时器,在页面不可见或失去焦点时会自动暂停,直到页面重新可见或获得焦点时才会继续执行。 这是浏览器的默认行为,无需额外处理。

如果你希望即使在页面不可见时仍然执行代码,可以考虑使用 setTimeout 或 setInterval 这样的定时器函数,它们在页面不可见时仍会继续执行。不过请注意,频繁的定时器操作可能会对性能产生负面影响,因此需要谨慎使用。

如果不用 requestAnimationFrame,也可以用别的方法实现-->离开页面时定时器停止,回到页面时定时器继续走动的效果

方法:可以利用 window 对象的 blur 和 focus 事件来监听页面失去焦点和获得焦点的状态。

requestAnimationFrame是什么?

答:requestAnimationFrame 是浏览器提供的一个用于执行动画效果的 API。

它接收一个回调函数作为参数,并在下一次浏览器重绘之前执行该回调函数。

浏览器通常以每秒60帧(即每秒60次重绘)的速度运行动画,因此 requestAnimationFrame 的回调函数约每16.6毫秒(1000ms / 60)调用一次。

使用 requestAnimationFrame 可以确保动画在最佳的性能下运行,因为它会在浏览器准备好绘制下一帧之前执行回调函数。

这样可以避免不必要的重绘和浪费的资源。

需要注意的是,requestAnimationFrame 返回一个标识符(或称为句柄),可以使用该标识符来取消动画帧请求,使用 cancelAnimationFrame 函数进行取消操作。

代码demo:

scala 复制代码
  const { days, hours, minutes, seconds } = useCountDown2(
    new Date("2023-08-22T03:35:00.000Z").getTime()
  );
scala 复制代码
import { useState, useEffect } from "react";

const oneDay = 1000 * 60 * 60 * 24;
const oneHour = 1000 * 60 * 60;
const oneMinute = 1000 * 60;
const oneSecond = 1000;

let timer=null;
export function useCountDown2(endDate) {

    const [days, setDay] = useState('00');
    const [hours, setHour] = useState('00');
    const [minutes, setMinute] = useState('00');
    const [seconds, setSecond] = useState('00');


    
    const [endTime]=useState(endDate);

    useEffect(() => {

      const setLeftTime = () => {
        //requestAnimationFrame 的单位是毫秒(ms)
        const nowTime=Math.ceil(new Date().getTime());
        const diff = endTime - nowTime;
        let msec = diff;
        const d = Math.floor(msec / oneDay);
        msec -= d * oneDay;
        const hh = Math.floor(msec / oneHour);
        msec -= hh * oneHour;
        const mm = Math.floor(msec / oneMinute);
        msec -= mm * oneMinute;
        const ss = Math.floor(msec / oneSecond);
        msec -= ss * oneSecond;
        setDay(`${d}`.replace(/^\d$/, '0$&'));
        setHour(`${hh}`.replace(/^\d$/, '0$&'));
        setMinute(`${mm}`.replace(/^\d$/, '0$&'));
        setSecond(`${ss}`.replace(/^\d$/, '0$&'));
  
        timer= requestAnimationFrame(setLeftTime);

        if (endTime < nowTime) {
          console.log("销毁")
         return cancelAnimationFrame(timer);
        }
        console.log(`${mm}`.replace(/^\d$/, '0$&'),`${ss}`.replace(/^\d$/, '0$&'))
      };
  
    
      if (endTime && endTime > Math.ceil(new Date().getTime())) {
        timer= requestAnimationFrame(setLeftTime);
      }
  
      return () => {
        // 清除定时器
        console.log('销毁@------@')
        cancelAnimationFrame(timer);
      };
  
    }, [endTime]);
  
  


  return {
   days,hours,minutes,seconds,
  };
}

结论:经测试,从图中确实可以看出,当离开页面的时候,requestAnimationFrame中的代码暂停执行,减少了资源的消耗

相关推荐
ONE_PUNCH_Ge几秒前
Go 语言泛型
开发语言·后端·golang
东东5161 分钟前
果园预售系统的设计与实现spingboot+vue
前端·javascript·vue.js·spring boot·个人开发
rainbow68893 分钟前
Python学生管理系统:JSON持久化实战
java·前端·python
打小就很皮...6 分钟前
React Router 7 全局路由保护
前端·react.js·router
起风的蛋挞15 分钟前
Matlab提示词语法
前端·javascript·matlab
有味道的男人16 分钟前
1688获得商品类目调取商品榜单
java·前端·spring
leaves falling17 分钟前
c语言单链表
c语言·开发语言
独自破碎E20 分钟前
【中心扩展法】LCR_020_回文子串
java·开发语言
XLYcmy22 分钟前
一个用于统计文本文件行数的Python实用工具脚本
开发语言·数据结构·windows·python·开发工具·数据处理·源代码