Building FocusFlow - A Personal Task Timer with React

Adeel HussainAdeel Hussain
5 min read

FocusFlow is a simple yet functional task timer built with React. It allows users to set a timer for a task, see it countdown, and reset it when needed. The project was a great opportunity to learn about handling state, effects, and user input in React, but it also presented several challenges that I had to troubleshoot along the way. In this post, I will walk you through the steps I took to build this app, the errors I faced, how I solved them, and what I learned.

Project Overview

The idea for FocusFlow came from the need for a simple and effective tool to help with time management. The app consists of a task input area and a timer that counts down the time once you start it. If the timer runs out, a message appears saying "Task Complete."

App Features:

  1. Task Input: A user enters a task, which is tracked as state.

  2. Timer: A timer starts at a set value (e.g., 25 minutes or 1500 seconds), counts down, and resets when completed.

  3. Reset: A reset button allows you to set the timer back to the initial value.

The Development Journey

1. Starting with the Basic Structure

I started by building the basic components of the app: App.js, Timer.jsx, Content.jsx, and Header.jsx. The App.js file holds the main logic, while Content.jsx is where the user can input their task, and Timer.jsx is responsible for displaying and controlling the timer.

2. Handling the Timer Logic

One of the most important parts of this app was the timer logic. I initially set the timer state to 1500 seconds (25 minutes). I then used useEffect to manage the countdown behavior:

useEffect(() => {
  let interval;
  if (isRunning && timer > 0) {
    interval = setInterval(() => {
      setTimer((prevTimer) => prevTimer - 1);
    }, 1000);
  }

  if (timer === 0) {
    setIsRunning(false);
  }

  return () => clearInterval(interval);
}, [isRunning, timer]);

This code works by decreasing the timer state every second. When the timer hits 0, it stops the countdown and prevents further changes.

3. Debugging: Timer Was Going Too Fast

At one point, the timer started counting down too quickly — more like seconds instead of minutes. After some investigation, I realised the issue was with the setInterval function, which was firing too frequently. I had originally set the interval time to 1500 milliseconds (1.5 seconds), which caused the timer to decrement too quickly.

interval = setInterval(() => {
  setTimer((prevTimer) => prevTimer - 1);
}, 1000);

Now the timer counted down properly!

4. Handling the "Task Complete" Message
After fixing the timer's speed, I also had to address the issue of displaying the "Task Complete" message when the timer hit zero. Initially, the message would flicker and disappear almost immediately after showing. This happened because the timer was resetting as soon as it reached 0, which caused the component to re-render, and the message disappeared.

Solution: To fix this, I added a check to stop the timer from resetting immediately when the countdown finished. Here’s the updated code:

if (timer === 0) {
  setIsRunning(false); // Stop the timer when it reaches 0
}

By ensuring that the timer wouldn't reset to 1500 seconds on reaching 0, the message remained visible until the user interacted with the app again.

5. Handling User Input and Timer Start

I also ran into an issue where if the user clicked "Start Timer" without entering a task, the app would proceed without validation. To address this, I added a simple check to ensure that a task had been entered before starting the timer:

function running() {
  if (input === "") {
    alert("Enter a task!");
  } else {
    setIsRunning(true);
  }
}

This prevented the timer from starting if the input field was empty and gave the user a prompt to enter a task.

6. Debugging with Chrome DevTools

During development, I ran into a lot of problems with the app pausing in the debugger unexpectedly. The issue appeared to be with breakpoints that I had accidentally set in my code. To resolve this, I had to inspect and remove breakpoints in Chrome's developer tools.

Steps to remove breakpoints:

  1. Open DevTools (Ctrl + Shift + I or Cmd + Option + I).

  2. Go to the Sources tab.

  3. Look for any active breakpoints marked by blue dots beside the line numbers.

  4. Right-click on the line number and remove the breakpoint, or use the "Remove All Breakpoints" option.

This helped me get back to normal debugging and allowed me to continue with the app's development.

What I Learned

React State Management

Through this project, I got a deeper understanding of React's state management using useState and useEffect. Managing the state of the timer and user input was essential, and I had to carefully manage side effects (like the countdown timer) using useEffect.

Conditional Rendering

Conditional rendering was critical in showing the "Task Complete" message when the timer finished. I learned how to conditionally render content based on the state, and this helped in delivering a better user experience.

Error Debugging

Debugging React apps is always a challenge, and I encountered several issues with timing, state updates, and breakpoints. I learned how to use Chrome DevTools effectively to troubleshoot and identify issues quickly. The experience taught me how important it is to carefully inspect and remove breakpoints during development.

User Validation

I also realised the importance of user validation. Simple checks like ensuring the user has entered a task before starting the timer can prevent unnecessary errors and provide a smoother experience.

Conclusion

Building FocusFlow was a rewarding experience that helped me dive deeper into React and JavaScript development. I faced several challenges, including debugging issues, managing state, and handling conditional rendering, but solving these problems gave me a better understanding of React and front-end development in general.

In the end, I now have a functional task timer that can be used to help with productivity, and the process taught me valuable lessons that I’ll carry with me into future projects.

Github Link - https://github.com/AdeelH12/FocusFlow

0
Subscribe to my newsletter

Read articles from Adeel Hussain directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Adeel Hussain
Adeel Hussain