DEV Community

Cover image for How To Create A Timer With React

How To Create A Timer With React

Julia πŸ‘©πŸ»β€πŸ’» GDE on July 27, 2022

For one of my current projects, I created a timer until the release on New Year's Eve - December 31, 2022. Since the project is written in React, I...
Collapse
 
raibtoffoletto profile image
RaΓ­ B. Toffoletto •

Nice beginner article @yuridevat and great comment @lukeshiru . I also would rather store the unix timespan than the values individually, it makes easier to do math with it and you wouldn't need even to setTime a new timespan every second, a simple subtraction would do the trick. =D

Building on that, here's a handy hook:

import { useState, useEffect } from "react";

const SECOND = 1_000;
const MINUTE = SECOND * 60;
const HOUR = MINUTE * 60;
const DAY = HOUR * 24;

export default function useTimer(deadline, interval = SECOND) {
  const [timespan, setTimespan] = useState(new Date(deadline) - Date.now());

  useEffect(() => {
    const intervalId = setInterval(() => {
      setTimespan((_timespan) => _timespan - interval);
    }, interval);

    return () => {
      clearInterval(intervalId);
    };
  }, [interval]);

  /* If the initial deadline value changes */
  useEffect(() => {
    setTimespan(new Date(deadline) - Date.now());
  }, [deadline]);

  return {
    days: Math.floor(timespan / DAY),
    hours: Math.floor((timespan / HOUR) % 24),
    minutes: Math.floor((timespan / MINUTE) % 60),
    seconds: Math.floor((timespan / SECOND) % 60)
  };
}
Enter fullscreen mode Exit fullscreen mode

Then its simple to use:

const { days, hours, minutes, seconds } = useTimer("2022-12-31T23:59:59");
Enter fullscreen mode Exit fullscreen mode
 
raibtoffoletto profile image
RaΓ­ B. Toffoletto •

Yes good point! But as far I remember it deviates very irregularly in the milliseconds, so I tend to ignore it unless it's crucial πŸ˜…. But thanks for the video link, I'll watch it to refresh my memory on the subject 😁.

In that case only one useEffect is needed:

useEffect(() => {
    const intervalId = setInterval(() => {
      setTimespan(new Date(deadline) - Date.now());
    }, interval);

    return () => {
      clearInterval(intervalId);
    };
  }, [deadline, interval]);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
yuridevat profile image
Julia πŸ‘©πŸ»β€πŸ’» GDE •

Wow! Thank you for your suggestion! Since my tutorial is a beginner tutorial, I won't change it, but will include your comment in the article, because it could be very important for those who want to write the code in a professional way and this comment must not be overlooked in any case!

I myself will study your solution to fully understand it. It's time for me to finally write code in a professional way! You really made my day, thanks again!

Collapse
 
yuridevat profile image
Julia πŸ‘©πŸ»β€πŸ’» GDE •

Thank you so much for your suggestions, I will insert most of your suggestions (the ones I get πŸ˜…) right away!

Doh', I thought that I did not fully understand setInterval/clearInterval and useEffect. I will read about it again and update the information.

Thank you for helping me making this tutorial better, I really appreciate it.

Collapse
 
francoisaudic profile image
francoisaudic •

For the HTML, you could put a Β« timer Β» role and an attribute tabindex="0" on the container of the timer.

Collapse
 
yuridevat profile image
Julia πŸ‘©πŸ»β€πŸ’» GDE •

Shame on me. Thank you very much for this advice, Francois. I should indeed include accessible code in my (future) tutorials from the beginning, and not only for my accessibility articles themselves. I will do my research and implement it. I will keep you posted when I have revised the code.

Thank you for supporting me in getting better at accessibility every day.

Collapse
 
samuel_kelv profile image
Samuel Kelv •

The explanation is beginner friendly. Kudos

Collapse
 
yuridevat profile image
Julia πŸ‘©πŸ»β€πŸ’» GDE •

Thanks, Samuel.

Collapse
 
moopet profile image
Ben Sinclair •

Hi, you're missing a closing quote everywhere you mention <div className="timer> :)

Collapse
 
yuridevat profile image
Julia πŸ‘©πŸ»β€πŸ’» GDE •

Copy paste 😌. Very attentive, thank you!

Collapse
 
yuridevat profile image
Julia πŸ‘©πŸ»β€πŸ’» GDE •

Hey Kaio! Could you please remove the link in your comment since this is not the right place to post it, thanks!

Collapse
 
joniedev profile image
Okoro John •

Nice peace. Many thanks.