🐣 [React] setIntervalのレンダリング(頭の整理)
作成日: 2022/02/22
6

下記だとtimerが0になっても止まらない。(最初のtimerの値を参照し続けてしまう)

const [timer, setTimer] = useState(timeSetting)

useEffect(() => {
  tick = setInterval(() => {
    console.log('tick')
    if (timer > 0) {
      setTimer(prev => prev - 1)
    } else {
      clearInterval(tick)
    }
  }, 1000)
  return () => {
    console.log('clear')
    clearInterval(tick)
  }
}, [])

useEffectの第二引数に timer を入れると、毎回useEffectの中身が更新されるのでsetIntervalとclearIntervalが繰り返される。

timer が更新されるたびに timer の値をrefに保存しておくとGOOD。

const [timer, setTimer] = useState(timeSetting)
const timeRef = useRef(timer)

useEffect(() => {
  tick = setInterval(() => {
    console.log('tick')
    if (timeRef.current > 0) {
      setTimer(prev => prev - 1)
    } else {
      clearInterval(tick)
      onCountOver()
    }
  }, 1000)
  return () => {
    console.log('clear')
    clearInterval(tick)
  }
}, [])

useEffect(() => {
  timeRef.current = timer
}, [timer])

制作会社でフロントのコーディングやWordpressのテーマ開発をしてます。 本命はJavascriptです😋 目指せフロントエンドエンジニア👊