How to create a Stopwatch in React ⏱️?
Tags: react, javascript, machinecoding, ui
Published: 2024-01-16 06:01:25

### What is Stopwatch ?

A Stopwatch which can be started and stopped by pressing a button, so that you can measure exactly how long something takes.

In this blog we learn to create stopwatch which show hours, minutes, seconds and milliseconds in ReactJs. By the end of this article, you will have a clear understanding of how to build a functional stopwatch in React.

**Source Code** : [codesandbox](https://codesandbox.io/p/sandbox/stopwatch-jsnv8h)

### Project Setup
First, you need to create a React project. In the terminal of your text editor and at your chosen directory, type in this command :

```
npx create-react-app stopwatch-app
```

#### Create initial state :
Create two variable state for determine time and current running status of watch.

```
  const [time, setTime] = useState(0);
  const [isRunning, setIsRunning] = useState(false);
```

#### Add handlers for start & stop and reset :
Lets create two onClick handlers one for play and stop the watch and other to reset the watch. 

```
  const onHandlePlayAndStop = () => {
    setIsRunning((pre) => !pre);
  };

  const onHandleReset = () => {
    setIsRunning(false);
    setTime(0);
  };
```

#### Add time logic :
Lets take variables to show hours, minutes ,seconds and milliseconds apply with logic.

```
  const hours = Math.floor(time / 360000);
  const mins = Math.floor((time % 36000) / 6000);
  const secs = Math.floor((time % 6000) / 100);
  const milliSecs = Math.floor(time % 100);
```

#### Add UI to show watch with styles.
Now, create watch and show all time varialbes and add padStart() function to show double numbers on screen like exact as a stopwatch.

```
//Stopwatch.jsx
 <div className="stopwatch-container">
      <div className="stopwatch-wrapper">
        <h2>Stopwatch ⏱️</h2>
        <div className="stopwatch-timer">
          {hours.toString().padStart(2, "0")}:{mins.toString().padStart(2, "0")}
          :{secs.toString().padStart(2, "0")}:
          {milliSecs.toString().padStart(2, "0")}
        </div>
        <div className="stopwatch-btn-wrapper">
          <button onClick={onHandlePlayAndStop} className="stopwatch-btn">
            {isRunning ? "Pause" : "Play"}
          </button>
          <button onClick={onHandleReset} className="stopwatch-btn">
            Reset
          </button>
        </div>
      </div>
    </div>
```

#### Adding styles
```
//Styles.css

body {
  background-image: url("https://images.pexels.com/photos/339119/pexels-photo-339119.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1");
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}

.stopwatch-wrapper {
  padding: 10px 50px 30px;
  text-align: center;
  background: rgba(255, 255, 255, 0.11);
  border-radius: 16px;
  box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(4.9px);
  -webkit-backdrop-filter: blur(4.9px);
  border: 1px solid rgba(255, 255, 255, 0.26);
}

.stopwatch-wrapper h2 {
  color: #fff;
}

.stopwatch-timer {
  font-size: 80px;
  color: #fff;
}

.stopwatch-btn-wrapper {
  display: flex;
  justify-content: space-between;
}

.stopwatch-btn-wrapper button {
  width: 48%;
  border: none;
  border-radius: 5px;
  padding: 10px 0;
  color: #fff;
  font-size: 16px;
  font-weight: 700;
}

.stopwatch-btn-wrapper button:first-child {
  background-color: green;
}

.stopwatch-btn-wrapper button:last-child {
  background-color: red;
}

```
 
#### Managing States using side-effects
To make it working we will use Web-API : setInterval() function and apply inside a useEffect hook and after updating the time state, we will clear the effect by using return clearInterval() function.

```
  useEffect(() => {
    let intervalCall;
    if (isRunning) {
      intervalCall = setInterval(() => setTime((pre) => pre + 1), 10);
    }
    return () => clearInterval(intervalCall);
  }, [isRunning]);

```

### Full Code is here : 

```
//Stopwatch.jsx
import { useEffect, useState } from "react";
import "./styles.css";

const Stopwatch = () => {
  const [time, setTime] = useState(0);
  const [isRunning, setIsRunning] = useState(false);

  useEffect(() => {
    let intervalCall;
    if (isRunning) {
      intervalCall = setInterval(() => setTime((pre) => pre + 1), 10);
    }
    return () => clearInterval(intervalCall);
  }, [isRunning]);

  const hours = Math.floor(time / 360000);
  const mins = Math.floor((time % 36000) / 6000);
  const secs = Math.floor((time % 6000) / 100);
  const milliSecs = Math.floor(time % 100);

  const onHandlePlayAndStop = () => {
    setIsRunning((pre) => !pre);
  };

  const onHandleReset = () => {
    setIsRunning(false);
    setTime(0);
  };

  return (
    <div className="stopwatch-container">
      <div className="stopwatch-wrapper">
        <h2>Stopwatch ⏱️</h2>
        <div className="stopwatch-timer">
          {hours.toString().padStart(2, "0")}:{mins.toString().padStart(2, "0")}
          :{secs.toString().padStart(2, "0")}:
          {milliSecs.toString().padStart(2, "0")}
        </div>
        <div className="stopwatch-btn-wrapper">
          <button onClick={onHandlePlayAndStop} className="stopwatch-btn">
            {isRunning ? "Pause" : "Play"}
          </button>
          <button onClick={onHandleReset} className="stopwatch-btn">
            Reset
          </button>
        </div>
      </div>
    </div>
  );
};

export default Stopwatch;

//style.css
body {
  background-image: url("https://images.pexels.com/photos/339119/pexels-photo-339119.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1");
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}

.stopwatch-wrapper {
  padding: 10px 50px 30px;
  text-align: center;
  background: rgba(255, 255, 255, 0.11);
  border-radius: 16px;
  box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(4.9px);
  -webkit-backdrop-filter: blur(4.9px);
  border: 1px solid rgba(255, 255, 255, 0.26);
}

.stopwatch-wrapper h2 {
  color: #fff;
}

.stopwatch-timer {
  font-size: 80px;
  color: #fff;
}

.stopwatch-btn-wrapper {
  display: flex;
  justify-content: space-between;
}

.stopwatch-btn-wrapper button {
  width: 48%;
  border: none;
  border-radius: 5px;
  padding: 10px 0;
  color: #fff;
  font-size: 16px;
  font-weight: 700;
}

.stopwatch-btn-wrapper button:first-child {
  background-color: green;
}

.stopwatch-btn-wrapper button:last-child {
  background-color: red;
}

```
### Result :

![Stopwatch Ui](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xa103ywl3cu1cfu8hgiw.png)

### Conclusion:

By apply these steps, you've successfully created a stopwatch in React. And also Understanding the logic behind this for building more complex applications. Thanks for reading.

Happy coding!

### Follow Me on Social Media!
If you found this blog helpful, feel free to connect with me on LinkedIn and follow me on github too for more programming tips and tutorials.

LinkedIn: [https://www.linkedin.com/in/nonish-jain-707397169](https://www.linkedin.com/in/nonish-jain-707397169)

Github : [https://github.com/Nonish](https://github.com/Nonish)