DEV Community

Cover image for Creating a Lap Timer in React
Nolan Miller
Nolan Miller

Posted on • Edited on

Creating a Lap Timer in React

Another late night with lofi music plaing in my office working on Roast.

Not quite so late as last night, and I spent a good amount of time tonght doing housework, but I made a lot of progress this morning and in my session tonight!

The Output

Status Component Lap Timer

The work today, is the second page in the roast flow. This the meat of the front end functionality. It’s the screen where you actually do the roasting!

I’m very happy with how the animations turned out. The solution was conditionally changing colors, background colors, and font sizes based on the step state that I had already implemented!

The hardest part of this was doing pixel calculations to figure out how to get the size changes to not bounce the whole UI all over the place.

Making a Working Lap Timer

While this is an app for roasting coffee, the functionality is essentially a lap timer for a stop watch. This one functions by setting a value within the Roast instance and displaying that value on screen when the “Record Step" button is playing.

Here’s everything I had to implement to make this work for my project. You will be able to see how this applies to other types of time recording.

Create an Object to Store The Data to Display

I chose to create a class for my Roasts so that I can create them more easily throughout the application. Below, I’ve omitted some of the properties from the constructor for clarity:

// roasts.js
class Roast {
    constructor(date) {
        // other roast properties
        this.tempRiseSeconds = null
        this.firstCrackSeconds = null
        this.tempRiseSeconds = null
        this.openedLidSeconds = null
        this.heatOffSeconds = null
        this.dumpedSeconds = null
    }
}
Enter fullscreen mode Exit fullscreen mode

The actual object will be created in the next step.

Handle the Records

If you’d like more information on the timer, and the flow of the application, take a look at the past few days in this series. I have attached the start() function of my timer module to the flow of the application.

Although the data is displayed to the user in a component called Status.js , I've chosen to control the data within its parent component, Roaster.js .

Notice that the roast object, an instance of Roast is passed into the Roaster as a prop along with its setter. In the next component up, the state of this roast object is being managed, since it will be saved to the library once the Roaster component is unmounted.

// Roaster.js
// imports ...

const Roaster = ({ roast, setRoast }) => {
  // State to move through the roast process
  const [progress, setProgress] = useState("start-roast-form");
  const [roastStep, setRoastStep] = useState(1);
  // Timer module mount
  const { time, start, pause, reset, status} = useTimer();

  const nextProgress = () => { /* Application flow logic */ }
  const nextStep = () => { /* Push roast to the next roastStep */ }

   // Log the roast timing
  const logTime = () => {
    let key = '';
    if (roastStep === 1) key = 'firstCrackSeconds'
    if (roastStep === 2) key = 'tempRiseSeconds'
    if (roastStep === 3) key = 'openedLidSeconds'
    if (roastStep === 4) key = 'heatOffSeconds'
    if (roastStep === 5) key = 'dumpedSeconds'
    setRoast(prev => ({
      ...prev,
      [key]: time
    }))
  }

  // Moves to next step and logs the time
  const handleRecordStep = () => {
    logTime();
    nextStep();
  }
}
Enter fullscreen mode Exit fullscreen mode

The key here, is the logTime function, which copies the state from the previous state of the roast object passed in, and then dynamically sets the proper key to the current time of the stopwatch.

The logic is then packaged with the nextStep() function in handleRecordStep() .

It turns out, it's not too complex to log real-time events using a timer in React. Hope it helps with a future project!


Check Out the Repo

If you want to keep up with the changes, fork and run locally, or even suggest code changes, here’s a link to the GitHub repo!

https://github.com/nmiller15/roast

Top comments (0)