How To Create A Timer With React
Tags: react, tutorial, beginners
Published: 2022-07-27 10:29:00

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 also created the timer using the same setup.

_This is the first tutorial I have written. I have done my best to explain each step as accurately as possible 😬._

## Table of content

1. [Init React Project](#chapter-1)
2. [Create Timer Component](#chapter-2)
3. [Get The Code](#chapter-3)
4. [Get Advanced Code](#chapter-4)

---

## 1. Init React Project<a name="chapter-1"></a>

If you want to add the timer to an existing project, you can [skip this part](#chapter-2). If you don't have a React project set up yet, use your console to go to the folder where you want to save your project by using

`cd folder-name`

and write

`npx create-react-app my-app`

in the console to initialize the project. After the project is ready, write

`cd my-app`

to go into the project folder,

`code .`

to open it in Visual Studio Code (if you are using this IDE), and 

`npm start`

to run the project in `localhost:3000`.

You can find further instructions under [create react app](https://create-react-app.dev/docs/getting-started) or the [official React docs](https://reactjs.org/docs/create-a-new-react-app.html).

## 2. Create Timer Component<a name="chapter-2"></a>

In your `src` folder, create a new file called `Timer.js`.

Then, create a React arrow function component with the same name as the file and add the return statement. Don't forget to export the function.

```jsx
// Timer.js

import React from 'react';

const Timer = () => {

  return (
    <div className="timer">
    </div>
  );
};

export default Timer;
```

### Initialize variables

We start the function by importing the `useState()` hook (a built-in function) from React and creating the states we need. For a timer of this length we need _days_, _hours_, _minutes_ and _seconds_. I have set the default value to `0` since we are dealing with integers.

```jsx
// Timer.js

import React from 'react';
import { useState } from 'react';

const Timer = () => {
  const [days, setDays] = useState(0);
  const [hours, setHours] = useState(0);
  const [minutes, setMinutes] = useState(0);
  const [seconds, setSeconds] = useState(0);

  return (
    <div className="timer">
    </div>
  );
};

export default Timer;
```

### Initialize deadline

We need a specific date for how long the timer should run. In this case, I chose New Year's Eve and declared it as a string value (which we will later convert to an integer) in a variable called _deadline_.

```jsx
// Timer.js

import React from 'react';
import { useState } from 'react';

const Timer = () => {
  const [days, setDays] = useState(0);
  const [hours, setHours] = useState(0);
  const [minutes, setMinutes] = useState(0);
  const [seconds, setSeconds] = useState(0);
  const [seconds, setSeconds] = useState(0);

  const deadline = "December, 31, 2022";

  return (
    <div className="timer">
    </div>
  );
};

export default Timer;
```

### Create function to get time

Now let's create a function that will calculate the time until this specific date. We need our declared variable _deadline_ in this function and can directly use it since it is declared within the scope of the `Timer` component.

To get the difference between today and our deadline, I created a new variable called _time_ and set its value to the value of _deadline_ minus the value of the current date.

To do this, we use JavaScript's built-in function [Date.parse()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse), which converts the declared string _deadline_ that we passed as prop into an integer that we can work with. 

The [Date.now()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now) method returns the number of milliseconds representing the current date.

```jsx
// Timer.js

import React from 'react';
import { useState } from 'react';

const Timer = () => {
  const [days, setDays] = useState(0);
  const [hours, setHours] = useState(0);
  const [minutes, setMinutes] = useState(0);
  const [seconds, setSeconds] = useState(0);

  const deadline = "December, 31, 2022";

  const getTime = () => {
    const time = Date.parse(deadline) - Date.now();

  return (
    <div className="timer">
    </div>
  );
};

export default Timer;
```

**Calculate values for variables**

Since _time_ is an int in milliseconds, we can now calculate and set the value of the _days_, _hours_, _minutes_ and _seconds_ until the deadline.

To get the values for each variable, we need to convert the milliseconds **to seconds** by dividing _time_ by 1000 (because 1000 milliseconds is 1 second).

To **get the minutes**, we have to divide _time_ by 1000 (to get the seconds) and divide by 60 (because 1 minute has 60 seconds).

To **get the hours**, we must divide _time_ in milliseconds by 1000 (to get the seconds), 60 (to get the minutes), and 60 again (because 1 hour has 60 minutes), summarized here in parentheses to 1000 * 60 * 60 (abbreviated 3.600.000 can be used).

To **get the days**, we need to divide _time_ in milliseconds by 1000 (to get the seconds), 60 (to get the minutes), 60 again (because 1 hour has 60 minutes), and 24 (because 1 day has 24 hours), summarized here in parentheses as 1000 * 60 * 60 * 24 (abbreviated 86.400.000 can be used).

After getting each value, we use the [remainder (%) operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder) to reset the values to 0 if, for example, the user passed 86.400.000 as milliseconds, which equals 24 hours.

> By default, the function rolls over the hours if they are greater than 24, e.g. if the milliseconds are 36 hours, the hours = hours % 24 line sets the hours to 12. Depending on your use case, you may not want to roll over the hours.

The built-in function [Math.floor()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) returns the largest integer that is less than or equal to the specified value. 

```jsx
// Timer.js

import React from 'react';
import { useState } from 'react';

const Timer = () => {
  const [days, setDays] = useState(0);
  const [hours, setHours] = useState(0);
  const [minutes, setMinutes] = useState(0);
  const [seconds, setSeconds] = useState(0);

  const deadline = "December, 31, 2022";

  const getTime = () => {
    const time = Date.parse(deadline) - Date.now();

    setDays(Math.floor(time / (1000 * 60 * 60 * 24)));
    setHours(Math.floor((time / (1000 * 60 * 60)) % 24));
    setMinutes(Math.floor((time / 1000 / 60) % 60));
    setSeconds(Math.floor((time / 1000) % 60));
  };

  return (
    <div className="timer">
    </div>
  );
};

export default Timer;
```

To get the timer to render after every second, we need to import the `useEffect()` hook and use it inside the component to get the current value. This hook is used when a state is going to be updated.

We will use the [setInterval() method](https://developer.mozilla.org/en-US/docs/Web/API/setInterval), which calls our `getTime()` function with the _deadline_ passed as prop, with a fixed time delay between each call of 1000 (in milliseconds, which is 1 second). 
And since this function is only called when the component is unmounted, we must clear the interval using the [clearInterval() function](https://developer.mozilla.org/en-US/docs/Web/API/clearInterval) to invoke a rerender.

```jsx
// Timer.js

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

const Timer = () => {
  const [days, setDays] = useState(0);
  const [hours, setHours] = useState(0);
  const [minutes, setMinutes] = useState(0);
  const [seconds, setSeconds] = useState(0);

  const deadline = "December, 31, 2022";

  const getTime = () => {
    const time = Date.parse(deadline) - Date.now();

    setDays(Math.floor(time / (1000 * 60 * 60 * 24)));
    setHours(Math.floor((time / (1000 * 60 * 60)) % 24));
    setMinutes(Math.floor((time / 1000 / 60) % 60));
    setSeconds(Math.floor((time / 1000) % 60));
  };

  useEffect(() => {
    const interval = setInterval(() => getTime(deadline), 1000);

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

  return (
    <div className="timer">
    </div>
  );
};

export default Timer;
```

### And that's it.
The functionality of the timer is now fully set up. You can now style each variable inside the return statement of the timer component `<div className="timer></div>` the way you want it. You can take a look at how I styled my code. Don't forget to import the timer component into the app component so it can be rendered.

## 3. Get The Code<a name="chapter-3"></a>

You can find the code and stylesheet embedded in the CodePen. Please note that there are therefore differences in the structure, as I mentioned in the tutorial. There are no additional files in the CodePen and all the code is in the JavaScript sections. Also, no imports have been made and the hooks start with React.useState and React.useEffect.

{% codepen https://codepen.io/YuriDevAT/pen/NWYvKXz %}

## 4. Get Advanced Code<a name="chapter-4"></a>

Luke Shiru has added a much more advanced code approach to my timer in the comments that I want to share with anyone who is more familiar with JavaScript or wants to be. Thanks again for sharing the code and making my article even better.

{% collapsible **See Luke Shiru's approach** %} 

```jsx
import { useEffect, useMemo, useState } from "react";

const SECOND = 1000;
const MINUTE = SECOND * 60;
const HOUR = MINUTE * 60;
const DAY = HOUR * 24;

export const Timer = ({ deadline = new Date().toString() }) => {
    const parsedDeadline = useMemo(() => Date.parse(deadline), [deadline]);
    const [time, setTime] = useState(parsedDeadline - Date.now());

    useEffect(() => {
        const interval = setInterval(
            () => setTime(parsedDeadline - Date.now()),
            1000,
        );

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

    return (
        <div className="timer">
            {Object.entries({
                Days: time / DAY,
                Hours: (time / HOUR) % 24,
                Minutes: (time / MINUTE) % 60,
                Seconds: (time / SECOND) % 60,
            }).map(([label, value]) => (
                <div key={label} className="col-4">
                    <div className="box">
                        <p>{`${Math.floor(value)}`.padStart(2, "0")}</p>
                        <span className="text">{label}</span>
                    </div>
                </div>
            ))}
        </div>
    );
};
```

{% endcollapsible %}





---
![Thank you](https://docs.google.com/uc?export=download&id=166Ecq6uBl61U14OUlkHOHIBv2ArKoumJ)

_Thanks for your reading and time. I really appreciate it!_