清除超时/间隔是否必须在`useEffect`响应钩子内?

时间:2019-10-20 15:46:50

标签: reactjs settimeout setinterval react-hooks use-effect

我想知道使用React挂钩时清除超时/间隔的正确方法和最佳实践是什么。例如,我有以下代码:

import React, { useState, useEffect, useRef } from 'react';

const Test = () => {
  const id = useRef(null)
  const [count, setCount] = useState(5)
  const [timesClicked, setTimesClicked] = useState(0)

  if (!count) {
    clearInterval(id.current)
  }

  useEffect(() => {
    id.current = setInterval(() => {
      setCount(count => count -1)
    }, 1000)

    return () => {
      clearInterval(id.current)
    }
  }, [])

  const onClick = () => setTimesClicked(timesClicked => timesClicked + 1)

  return (
    <div>countdown: {count >= 0 ? count : 0}
      <hr />
      Clicked so far: {timesClicked}
      {count >= 0 && <button onClick={onClick}>Click</button>}
    </div>
  )
}

count等于0时,间隔将在Test函数的主体中清除。在我见过的大多数示例中,互联网间隔都是在useEffect中清除的,这是强制性的吗?

2 个答案:

答案 0 :(得分:4)

在卸下组件之前,必须确保清除所有间隔。 卸载组件并清除它们后,间隔永远不会自动消失,clearInterval通常在useEffect(()=> {},[])内部被调用。

卸载组件时,将调用useEffect(()=> {},[])中保留的函数。

    return () => {
      clearInterval(id.current)
    }

通过检查此沙盒链接,您可以看到在组件内部设置的间隔永远不会自动消失。 https://codesandbox.io/s/cool-water-oij8s

除非调用clearInterval,否则间隔会一直保持下去。

答案 1 :(得分:1)

setInterval是重复执行的function,它返回间隔的id。当您使用此ID呼叫clearInterval时,将阻止该function重复。在特定的function中执行此操作不是强制性的,当您不再希望随后调用function时,需要清除它。如果需要的话,您可以在function返回的useEffect中调用它。