Реагировать на функциональный компонент: clearInterval () не очищает мой интервал - PullRequest
1 голос
/ 27 марта 2019

Я создаю простое приложение таймера.Когда пользователь нажимает кнопку воспроизведения, вызывается функция handlePlayPause.Я создал логическое значение isRunning, чтобы проверить, работает ли таймер.Если это не так, таймер запустится (эта первая часть работает), а если это так, вызывается функция pauseTimer.Эта последняя функция переключает isRunning обратно в false и должна очистить интервал.Однако интервал не очищается.Ты видишь, что я делаю не так?

Спасибо за помощь!

export default function App() {
  const [sessionLength, setSessionLength] = useState(25)
  const [breakLength, setBreakLength] = useState(5)
  const [timeLeft, setTimeLeft] = useState(25 * 60 * 1000)
  const [isRunning, setIsRunning] = useState(false)

  let intervalId = null

  let handlePlayPause = () => {
    if (!isRunning) {
      setTimeLeft(sessionLength * 60 * 1000)
      playTimer()
    } else if (isRunning) {
      pauseTimer()
    }
  }

  let playTimer = () => {
    setIsRunning(true)
    intervalId = setInterval(() => {
      setTimeLeft(timeLeft => timeLeft - 1000)
      parseToMinuteSeconds(timeLeft)
    }, 1000)
  }

  let pauseTimer = () => {
    setIsRunning(false)
    clearInterval(intervalId)
  }

  let resetAll = () => {
    setSessionLength(25)
    setBreakLength(5)
  }

  let parseToMinuteSeconds = timeInMilliseconds => {
    return //a string with the time in this format 00:00
  }

  return ( 
     <div className="App">
        <Background>
           <UpperMetalBand />
           <UpperPart />
           <LowerPart />
           <LowerMetalBand />
           <Wrapper>
              <Title>Pomodoro</Title>
              <Subtitle>TIMER</Subtitle>
              <PlayButton 
                  id="start_stop"
                  onClick = {handlePlayPause}
              >
                 <i className="fa fa-play" />
              </PlayButton>
              <Reload 
                 onClick={resetAll}
                 id="reset"
              >
                 <i className="fas fa-sync-alt" />
              </Reload>
              <Session 
                 setSessionLength={setSessionLength}
                 sessionLength={sessionLength}
              />
              <Break 
                 setBreakLength={setBreakLength}
                 breakLength={breakLength}
              />
              <span id="time-label">
                 <Timer id="time-left">00:00</Timer>
              </span>
           </Wrapper>
        </Background>
     </div>
  )
}

1 Ответ

1 голос
/ 27 марта 2019

Я думаю, проблема в том, как вы храните идентификатор интервала. когда мы используем компоненты функций и мы хотим хранить переменные «экземпляра», мы можем использовать хук useRef.

   let intervalId = useRef(null)

  let handlePlayPause = () => {
    debugger
    if (!isRunning) {
      setTimeLeft(sessionLength * 60 * 1000)
      playTimer()
    } else if (isRunning) {
      pauseTimer()
    }
  }

  let playTimer = () => {
    setIsRunning(true)
    intervalId.current = setInterval(() => {
      console.log('interval')
      setTimeLeft(timeLeft => timeLeft - 1000)
      parseToMinuteSeconds(timeLeft)
    }, 1000)
  }


  let pauseTimer = () => {
    setIsRunning(false)
    clearInterval(intervalId.current)
  }

Существует пример, аналогичный вашему случаю использования на реагирующих документах

...