25 + 5 clock timer Problem

Hi Guys, I have been working on 25 + 5 clock project since Morning and I have been facing a problem and I am stuck here from the last 3-4 hours reading about setInterval and settimeout but haven’t successful yet. Please help.

Here is the link of my complete code - Clock - CodeSandbox

Problem - When I pause the timer or reset it, It happens after 1sec.

This is my initial state value
const initialState = {
  sessionLength: 25,
  breakLength: 5,
  timer: `25:00`,
  active: "Session",
  activate: false,
};

//reset function is called when reset button is clicked. 
 const reset = () => {
    dispatch({ type: "RESET" });
  };

//reset button updates the state to initalvalue. 
case "RESET":
      return {
        ...state,
        sessionLength: 25,
        breakLength: 5,
        timer: `25:00`,
        active: "Session",
        activate: false,
      };


//This useEffect hook is responsible for updating timer Value whenever state value changes.

useEffect(() => {
    //only if session has been started

    if (!activate) {
      if (!timerRef.current) {
        clearTimeout(timerRef.current);
        timerRef.current = null;
      }
      return;
    }

    if (timer === "0:00") {
      let sound = document.getElementById("beep");
      sound.play();
      return dispatch({ type: "CHANGE_SESSION" });
    }
    //change active session_________________

    if (active === "Session") {
      timerRef.current = setTimeout(
        () => dispatch({ type: "UPDATE_SESSION" }),
        1000
      );
    }
    if (active === "Break") {
      timerRef.current = setTimeout(
        () => dispatch({ type: "UPDATE_BREAK" }),
        1000
      );
    } //___________________________
  }, [activate, active, timer]);



Please help. 


Here are my observations. I wrote this project in both plain JS and class-based React, but not with Hooks and Redux, so I can’t comment much on those aspects.

  1. I can still click on up / down buttons for the break and session length while the clock is active.

  2. The clock came back with Not Supported Error when reaching 00:00.

  3. I suggest you use just one variable to keep track of time left, instead of checking the session and break. You keep the state of a clock (either SESSION or BREAK) and assign time left to the session length or break length depending on the clock state. When the timer reaches 0, then you switch the state of the clock and continue. This makes the whole logic of managing the timer simpler.

  4. I think your useEffect is too complex. You want it as simple as possible. Relying on three states makes the things harder to manage. You really don’t want to deal with starting the timer and checking the value of ‘active’ in useEffect. As I suggested above, let’s say you have one state timeLeft. useEffect should just monitor this timeLeft state and the callback function simply updates the display based on the timeLeft value.

  5. The starting and stopping of the timer should be done in a method (outside of useEffect) that responds to the button click of start/pause. If the clock is running, then you stop the timer and set state of the timer to Not Running (isRunning is false). Otherwise, you start the timer and set the timer state to Running (isRunning is true). You use setInterval in start timer and clearInterval in stop timer. The starting of a timer will set countdown() function to be called every 1000 milliseconds. The countdown will update the time left every second. useEffect will pick up the state change and updates the display. In the countdown function, you check to continue count down or switch the clock.

2 Likes

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.