React怎么实现一个倒计时hook组件

其他教程   发布日期:2023年07月02日   浏览次数:436

这篇“React怎么实现一个倒计时hook组件”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“React怎么实现一个倒计时hook组件”文章吧。

思路

倒计时可能需要显示剩余时间的单位有:天、时、分、秒、毫秒,可能只需显示一个,也可能都需要显示。

注意细节:

  • 只显示某一单位的时间或者需要显示的最大单元时间,需要可以大于正常时间最大限制,比如要剩余 100 小时 58 分时,小时需要可以大于 23,分钟不能大于 59 。

  • 需要可以设置是否显示毫秒,1s等于1000ms,但人的反应时间是0.2s~0.3s,因此毫秒以百为单位显示,显示毫秒适用于秒杀类活动场景。

实现

先来定义好参数:

  1. export interface CountDownOptions {
  2. /** 截止时间,时间戳 */
  3. deadlineTime: number;
  4. /** 是否需要毫秒 */
  5. showMillisecond?: boolean;
  6. }

参数只需要倒计时截止时间以及是否需要显示毫秒。

再定义一下需要获取的返回值:

  1. export interface TimeInfo {
  2. /** 天 */
  3. day: number;
  4. /** 小时 */
  5. hours: number;
  6. /** 补零后的小时 */
  7. hoursStr: string;
  8. /** 分钟 */
  9. minutes: number;
  10. /** 补零后的分 */
  11. minutesStr: string;
  12. /** 秒 */
  13. seconds: number;
  14. /** 补零后的秒 */
  15. secondsStr: string;
  16. /** 毫秒 */
  17. milliseconds?: number;
  18. /** 补零后的毫秒 */
  19. millisecondsStr?: string;
  20. /** 是否结束 */
  21. end: boolean;
  22. }

  1. day
  1. hours
  1. minutes
  1. seconds
  1. milliseconds
都是剩余的多少秒数,没有做限制,
  1. hoursStr
  1. minutesStr
  1. secondsStr
  1. millisecondsStr
才做限制,比如剩下 1天10小时10分钟10秒100毫秒,那么显示结果如下:
  1. {
  2. day,
  3. hours,
  4. hoursStr,
  5. minutes,
  6. minutesStr,
  7. seconds,
  8. secondsStr,
  9. end: false,
  10. }

下面来看具体实现代码。

先实现一个简单的补零函数,JS字符串本身也有补零函数,也可以直接使用的,不过也需要转换类型。

  1. // 格式化数据,这里就是补零
  2. function formate(time: number): string {
  3. return `${time < 10 ? "0" : ""}${time}`;
  4. }

工具方法——清除倒计时数据数据信息:

  1. function clearCountdownInfo(showMillisecond = false): TimeInfo {
  2. const timeInfo: TimeInfo = {
  3. day: 0,
  4. hours: 0,
  5. hoursStr: "00",
  6. minutes: 0,
  7. minutesStr: "00",
  8. seconds: 0,
  9. secondsStr: "00",
  10. end: true,
  11. };
  12. if (showMillisecond) {
  13. timeInfo.milliseconds = 0;
  14. timeInfo.millisecondsStr = "0";
  15. }
  16. return timeInfo;
  17. }

关键工具方法——计算倒计时返回的数据信息:

  1. function computeCountdownInfo(
  2. remainTime: number,
  3. showMillisecond = false
  4. ): TimeInfo {
  5. // 剩余时间小于说明结束,直接清空
  6. if (remainTime < 0) {
  7. return clearCountdownInfo(showMillisecond);
  8. }
  9. // 这里用了一个比较笨的方法,一个个进行计算,后续可以优化试试看
  10. const day = Math.floor(remainTime / (24 * 60 * 60));
  11. const hours = Math.floor((remainTime / (60 * 60)) % 24);
  12. const hoursStr = formate(hours);
  13. const minutes = Math.floor((remainTime / 60) % 60);
  14. const minutesStr = formate(minutes);
  15. const seconds = Math.floor(remainTime % 60);
  16. const secondsStr = formate(seconds);
  17. // 组合成需要返回的时间信息
  18. const timeInfo: TimeInfo = {
  19. day,
  20. hours,
  21. hoursStr,
  22. minutes,
  23. minutesStr,
  24. seconds,
  25. secondsStr,
  26. end: false,
  27. };
  28. // 需要显示毫秒逻辑处理
  29. if (showMillisecond) {
  30. const milliseconds = Math.floor(remainTime * 1000);
  31. // 只取首位
  32. const millisecondsStr = String(milliseconds).slice(-3);
  33. timeInfo.milliseconds = milliseconds;
  34. timeInfo.millisecondsStr = millisecondsStr;
  35. }
  36. return timeInfo;
  37. }

核心逻辑 &mdash;&mdash;

  1. useCountdown
hook 组件:
  1. export const useCountdown = (options: CountDownOptions) => {
  2. // 首次初始化数据,显示清除的数据
  3. const [timeInfo, setTimeInfo] = useState<TimeInfo>(
  4. clearCountdownInfo(options.showMillisecond)
  5. );
  6. useEffect(() => {
  7. let timer = 0;
  8. function countdown() {
  9. const remainTime = computeRemainTime(options.deadlineTime);
  10. // 剩余时间大于 0 才开始倒计时
  11. if (remainTime > 0) {
  12. // 未结束时直接定时下一次在执行判断 countdown
  13. timer = window.setTimeout(
  14. countdown,
  15. options.showMillisecond ? 100 : 1000 // 毫秒级则修改定时器时间
  16. );
  17. }
  18. const data = computeCountdownInfo(remainTime, options.showMillisecond);
  19. setTimeInfo(data);
  20. }
  21. // 开始倒计时
  22. countdown();
  23. return () => {
  24. // 清除定时器
  25. timer && clearInterval(timer);
  26. };
  27. }, [options.deadlineTime, options.showMillisecond]);
  28. return timeInfo;
  29. };

上面需要注意一下,服务端渲染的情况不要首次进行render的时候初始化数据,会和服务端已经不一致导致 hydrate 报错。

客户端渲染的可以在render的时候初始化代码:

  1. // 渲染时获取一次剩余时间
  2. const remainTime = useMemo(
  3. () => computeRemainTime(options.deadlineTime),
  4. [options.deadlineTime]
  5. );
  6. // 首次初始化数据,以防页面闪烁
  7. const [timeInfo, setTimeInfo] = useState<TimeInfo>(
  8. computeCountdownInfo(remainTime)
  9. );

以上就是React怎么实现一个倒计时hook组件的详细内容,更多关于React怎么实现一个倒计时hook组件的资料请关注九品源码其它相关文章!