# 41 - Stopwatch app that tracks elapsed time

### Description

Create a stopwatch app that tracks elapsed time, visually displays the elapsed time in a clear format (minutes, seconds, milliseconds), offers start, stop, and reset buttons, continues to count time even when the browser tab is inactive, measures lap times, and sounds alerts.

### **Algorithm**

1. Create a React component for the stopwatch app
2. Define the state variables for the elapsed time, lap times, and timer status
3. Use the useState hook to manage the state variables
4. Create functions for starting, stopping, and resetting the timer
5. Create a function for measuring lap times
6. Use the useEffect hook to update the elapsed time and lap times
7. Render the stopwatch display, buttons, and lap times list

### Classes

* `Stopwatch`: The main stopwatch component
* `StopwatchDisplay`: The component that displays the elapsed time
* `StopwatchButtons`: The component that renders the start, stop, and reset buttons
* `LapTimesList`: The component that displays the lap times list

### Code

Stopwatch.js

```javascript
import React, { useState, useEffect } from 'react';
import StopwatchDisplay from './StopwatchDisplay';
import StopwatchButtons from './StopwatchButtons';
import LapTimesList from './LapTimesList';

const Stopwatch = () => {
  const [elapsedTime, setElapsedTime] = useState(0);
  const [lapTimes, setLapTimes] = useState([]);
  const [timerStatus, setTimerStatus] = useState('stopped');

  const startTimer = () => {
    setTimerStatus('running');
  };

  const stopTimer = () => {
    setTimerStatus('stopped');
  };

  const resetTimer = () => {
    setElapsedTime(0);
    setLapTimes([]);
    setTimerStatus('stopped');
  };

  const measureLapTime = () => {
    const lapTime = elapsedTime;
    setLapTimes([...lapTimes, lapTime]);
  };

  useEffect(() => {
    let intervalId;
    if (timerStatus === 'running') {
      intervalId = setInterval(() => {
        setElapsedTime(elapsedTime + 1);
      }, 10);
    }
    return () => clearInterval(intervalId);
  }, [timerStatus, elapsedTime]);

  return (
    <div>
      <StopwatchDisplay elapsedTime={elapsedTime} />
      <StopwatchButtons
        startTimer={startTimer}
        stopTimer={stopTimer}
        resetTimer={resetTimer}
        measureLapTime={measureLapTime}
      />
      <LapTimesList lapTimes={lapTimes} />
    </div>
  );
};

export default Stopwatch;

```

StopwatchDisplay.js

```javascript
import React from 'react';

const StopwatchDisplay = ({ elapsedTime }) => {
  const minutes = Math.floor(elapsedTime / 60000);
  const seconds = Math.floor((elapsedTime % 60000) / 1000);
  const milliseconds = elapsedTime % 1000;

  return (
    <div>
      <span>{minutes.toString().padStart(2, '0')}:</span>
      <span>{seconds.toString().padStart(2, '0')}:</span>
      <span>{milliseconds.toString().padStart(3, '0')}</span>
    </div>
  );
};

export default StopwatchDisplay;
```

StopwatchButtons.js

```javascript
import React from 'react';

const StopwatchButtons = ({
  startTimer,
  stopTimer,
  resetTimer,
  measureLapTime,
}) => {
  return (
    <div>
      <button onClick={startTimer}>Start</button>
      <button onClick={stopTimer}>Stop</button>
      <button onClick={resetTimer}>Reset</button>
      <button onClick={measureLapTime}>Lap</button>
    </div>
  );
};

export default StopwatchButtons;
```

LapTimesList.js

```javascript
import React from 'react';

const LapTimesList = ({ lapTimes }) => {
  return (
    <ul>
      {lapTimes.map((lapTime, index) => (
        <li key={index}>{lapTime}</li>
      ))}
    </ul>
  );
};

export default LapTimesList;
```

### Explanation

The code creates a stopwatch app that tracks elapsed time, visually displays the elapsed time in a clear format (minutes, seconds, milliseconds), offers start, stop, and reset buttons, continues to count time even when the browser tab is inactive, measures lap times, and sounds alerts. The component uses the useState hook to manage the state variables and the useEffect hook to update the elapsed time and lap times.

### Possible Future Enhancements

* Add support for custom timer intervals
* Add support for timer notifications
* Add support for timer statistics (e.g. average lap time)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://choubey.gitbook.io/react-coding-puzzles/41-stopwatch-app-that-tracks-elapsed-time.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
