React+TS利用自定义HOOKS实现倒计时

因为工作需要做一个秒杀活动的动态倒计时,

例如:

在掘金上看到的一篇文章,原文解释的更加清楚,原文链接:

react hooks 实现一个简单的倒计时 - 掘金首先,需要一个不断更新的当前时间(初始化可以用 moment 获取当前时间),时间获取后,设置一个每秒更新一次的定时器。 其次,还要通过比较每秒更新后的时间和用户传入的 deadline,计算剩余时间。 所以我们需要两个状态:current 和 remains。 current…https://juejin.cn/post/6942446310620397604于是就按照方法尝试了一下,

1.先创建一个名为 useCountdown 的文件

2.useCountdown文件的内容

import { useEffect, useState } from 'react';
import moment from 'moment';

// 入参
export interface ICountdown {
  deadline: string;
  format?: 'YYYY-MM-DD HH:mm:ss' | string;
}
// 返回值
export type Remains = Record<'day' | 'hour' | 'minute' | 'second', number>;

const useCountdown = ({
  deadline,
  format = 'YYYY-MM-DD HH:mm:ss',
}: ICountdown): Remains => {
  // 由于 moment() 返回对象,setCurrent 修改值后指针不变,无法在 useEffect 中捕获变化,所以这里定义了一个 updater 用于 useEffect 捕获时间更新
  const [{ current, updater }, setCurrent] = useState({
    current: moment(),
    updater: 0,
  });
  const [remains, setRemains] = useState<Remains>({
    day: 0,
    hour: 0,
    minute: 0,
    second: 0,
  });
  useEffect(() => {
    const timer = window.setInterval(() => {
      current.isSameOrAfter(moment(deadline, format))
        ? clearInterval(timer)
        : setCurrent(prev => ({
            current: prev.current.add(1, 's'),
            updater: prev.updater + 1,
          }));
    }, 1000);
    return () => clearInterval(timer);
  }, [deadline]);

  // current 变化,计算相差多长时间
  useEffect(() => {
    let millisec = moment(deadline, format).valueOf() - current.valueOf();
    // 处理 millisec 可能为负数的情况
    millisec = millisec >= 0 ? millisec : 0;
    // 用毫秒数得到秒、分、小时和天
    setRemains({
      day: Math.floor(millisec / (1000 * 60 * 60 * 24)),
      hour: Math.floor((millisec / (1000 * 60 * 60)) % 24),
      minute: Math.floor((millisec / (1000 * 60)) % 60),
      second: Math.round((millisec / 1000) % 60),
    });
  }, [updater]);

  return remains;
};

export default useCountdown;

 3.使用:

首先在需要用到定时器的页面引入

 然后插入代码

  const deadline = useMemo(
    () =>
      moment()
        // 设置时间
        .add(8, 's')
        .add(7, 'm')
        .add(6, 'h')
        .add(5, 'd')
        .format('YYYY-MM-DD HH:mm:ss'),
    [],
  );
  const { day, hour, minute, second } = useCountdown({
    deadline,
  });

 在自己需要用到的地方写格式

<p className='time'>{`距结束${day}天${hour}时${minute}分${second}秒`}</p>

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值