Create a custom React stopwatch timer component
Tags: javascript, react, tutorial, webdev
Published: 2022-05-25 05:12:14

In this tutorial we’ll be creating a React stopwatch timer component. The completed stopwatch component will display minutes, seconds, and milliseconds with start, stop, and reset functionality.

Let’s get started by setting up a dev environment using [Create React App](https://w3collective.com/create-react-app/):

`npx create-react-app react-stopwatch`

Next create a new `Stopwatch.js` file in the `/src` folder:

```javascript
import React, { useState, useEffect } from "react";

const Stopwatch = () => { 
  //...
};

export default Stopwatch;
```

We’ll be using two React Hooks, firstly `useState` which allows us to store state in a function based component. It’ll be used to store the stopwatch time and also whether or not the stopwatch is running. The `useEffect` Hook checks if the timer is running and if so updates the time.

In the `Stopwatch()` function we’ll first declare variables for the `time` and `running` states:

```javascript
const Stopwatch = () => {
  const [time, setTime] = useState(0);
  const [running, setRunning] = useState(false);  
  //...
};
```

Then we’ll calculate the time using a `useEffect()` Hook & `setInterval()` method:

```javascript
const Stopwatch = () => {
  const [time, setTime] = useState(0);
  const [running, setRunning] = useState(false);
  useEffect(() => {
    let interval;
    if (running) {
      interval = setInterval(() => {
        setTime((prevTime) => prevTime + 10);
      }, 10);
    } else if (!running) {
      clearInterval(interval);
    }
    return () => clearInterval(interval);
  }, [running]);
  //...
};
```

To complete the component we’ll output the time along with control buttons:

```javascript
const Stopwatch = () => {
  const [time, setTime] = useState(0);
  const [running, setRunning] = useState(false);
  useEffect(() => {
    let interval;
    if (running) {
      interval = setInterval(() => {
        setTime((prevTime) => prevTime + 10);
      }, 10);
    } else if (!running) {
      clearInterval(interval);
    }
    return () => clearInterval(interval);
  }, [running]);
  return (
    <div className="stopwatch">
      <div className="numbers">
        <span>{("0" + Math.floor((time / 60000) % 60)).slice(-2)}:</span>
        <span>{("0" + Math.floor((time / 1000) % 60)).slice(-2)}:</span>
        <span>{("0" + ((time / 10) % 100)).slice(-2)}</span>
      </div>
      <div className="buttons">
        <button onClick={() => setRunning(true)}>Start</button>
        <button onClick={() => setRunning(false)}>Stop</button>
        <button onClick={() => setTime(0)}>Reset</button>       
      </div>
    </div>
  );
};
```

The time is calculated by dividing the time by the number of milliseconds for each unit of time. We then use the remainder operator `%` to calculate if the time is divisible by 60 for seconds, 60 for minutes and, 100 for milliseconds. For example 1 minute 20 seconds is 80000 milliseconds so to calculate the seconds we do `(80000 / 1000) % 60 = 20`. Without the remainder operator `(80000 / 1000) = 80` we just get the total seconds.

Finally replace the contents of `App.js` to import and load the stopwatch component:

```javascript
import Stopwatch from "./Stopwatch";

const App = () => {
  return (
    <div className="App">
      <Stopwatch />
    </div>
  );
};

export default App;
```

That’s all for this tutorial, hopefully it’ll serve as a starting point for you to build more complex time based applications. Whilst you’re here be sure to checkout our ever expanding collection of [practical React tutorials](https://w3collective.com/tag/react/).