DEV Community

Nonish J.
Nonish J.

Posted on

How to create a Stopwatch in React ⏱️?

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

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
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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);
  };
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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;
}

Enter fullscreen mode Exit fullscreen mode

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]);

Enter fullscreen mode Exit fullscreen mode

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;
}

Enter fullscreen mode Exit fullscreen mode

Result :

Stopwatch Ui

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

Github : https://github.com/Nonish

Top comments (0)