反应功能组件:clearInterval()不会清除我的间隔

问题描述 投票:1回答:1

我正在构建一个简单的计时器应用程序。当用户单击播放时,将调用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>
  )
}
javascript reactjs react-hooks
1个回答
1
投票

我认为问题在于如何存储间隔ID。当使用函数组件并且我们想要存储“实例”变量时,我们可以使用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)
  }

你在react docs上的用例有一个类似的例子

© www.soinside.com 2019 - 2024. All rights reserved.