Pomodoro Clock: Can't get test #13 to pass

Tell us what’s happening:

Hello,

I have been working on React part of the Pomodoro Clock for quite a while but I can’t seem to get Test #13 to pass even though everything visually seems to be working.

Currently I’m using multiple state hooks to track such info as whether it is session or break, session length, break length, timer length (value in seconds that tracks time passed) and display time (a modified style of those timer length seconds to match mm:ss requirement), as well as whether the clock was paused:

const [ isSession, setIsSession ] = React.useState(DEFAULT_ISSESSION_VALUE)
  const [ sessionLength, setSessionLength ] = React.useState(DEFAULT_SESSION_LENGTH)
  const [ breakLength, setBreakLength ] = React.useState(DEFAULT_BREAK_LENGTH)
  
  const [ timerLength, setTimerLength ] = React.useState(DEFAULT_TIMER_LENGTH)
  const [ displayTime, setDisplayTime ] = React.useState(DEFAULT_DISPLAY_TIME)
  
  const [ startOrStop, setStartOrStop ] = React.useState(DEFAULT_START_OR_STOP)

I’m also using 2 useEffect and 1 useMemo hooks to modify those states.

First one is used to modify the timer value based on whether break or session value has been modified:

React.useEffect(() => {
    let time = (isSession ? sessionLength : breakLength) * 60
    setTimerLength(time)
  }, [sessionLength, breakLength])

The most complicated one, and that’s where I assume this error is happening is the following:

React.useEffect(() => {
    if (startOrStop && timerLength !== 0) {
      const timeout = setInterval(() => {
        setTimerLength(timerLength => timerLength - 1)
      }, 1000)
    
      return () => clearInterval(timeout)
    } else if (timerLength === 0) {
      setTimerLength(0)
      playAudio() 
      
      const timeout = setTimeout(() => {
        setIsSession(!isSession)
        let time = (isSession ? sessionLength : breakLength) * 60
        setTimerLength(time)
      }, 1000)
      
      return () => clearTimeout(timeout)
    }
  }, [startOrStop, timerLength])

Basically this useEffect hook is activated when the program is not paused and timer value is changing. In the “if” statement I set a one second interval that changes the timer value (and also clears it). The “else” statement is only supposed to be activated when timer is equal to 0 and it will set its value to 0, play a beep sound and then after one second it will change session to break, and vice versa, and reset the timer to the corresponding value from the session or break length in the state, as well as will clear this setTimeout function.

There’s also useMemo hook that basically sets the display value whenever timer value is changed:

React.useMemo(() => {
    let timerValues = displayingTime(timerLength)
    setDisplayTime(timerValues)
  }, [timerLength])

I noticed that if set up console.log in the return() part of the component, it seems that this component is rerendered 2 times with different values for display value and same timer value. For example, for timer value of 58, first display value will be 00:59 and second 00:58, and same for the value of 0 it will be displayed 00:01 and 00:00. I assume that testing script picks up this discrepancy between the values on the first render and that’s why this test fails.

However, I can’t figure out what exactly is the issue and how would I be able to fix it ?

Here is my pen for this problem just in case.

Best regards,
Konstantin

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36.

Challenge: Build a Pomodoro Clock

Link to the challenge: