文章

React Hook 和 setInterval一起使用的问题

React Hook 和 setInterval一起使用的问题

如果仅仅是用一个变量来保存tiner的ID,会导致无法清除timerID
如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const TimerCount = () => {
  let [count,setCount] = useState(0)
  let timer
  const handleStart =() => {
    timer = setInterval(() => {
      setCount(count++)
    },1000)
  }
  const handleEnd = () => {
    clearInterval(timer)
  }
  return (
    <>
    <button onClick={handleStart}>start</button>
    <button onClick={handleEnd}>end</button>
    <div>{count}</div>
    </>
  )
}

原因:

timer的id是一个number类型,每次在页面展示count时,都会 触发重新渲染,timer会被重新赋值,这是一个基本类型的值,需要清除的timer值已经不是原来的值了,虽然打印出来的是一样的值。

解决方案

用useRef,在整个渲染周期固定一个值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const TimerCount = () => {
  let [count,setCount] = useState(0)
  let timer = useRef<any>(null)
  const handleStart =() => {
    timer.current = setInterval(() => {
      setCount(count++)
    },1000)
  }
  const handleEnd = () => {
    clearInterval(timer.current)
  }
  return (
    <>
    <button onClick={handleStart}>start</button>
    <button onClick={handleEnd}>end</button>
    <div>{count}</div>
    </>
  )
}

这时timer是一个引用类型,里面的current属性保存了timer的id,并且整个渲染周期不变。使用ref访问DOM节点也是一样的原理

本文由作者按照 CC BY 4.0 进行授权