【问题标题】:Does clearing timeout/interval have to be inside `useEffect` react hook?清除超时/间隔是否必须在“useEffect”反应挂钩内?
【发布时间】:2020-02-16 20:31:37
【问题描述】:

我想知道在使用 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 中的间隔都被清除,这是强制性的吗?

【问题讨论】:

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


    【解决方案1】:

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

    在卸载组件时调用 useEffect(() => {}, []) 中返回的函数。

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

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

    除非调用clearInterval,否则间隔将永远保持。

    【讨论】:

    • 我的问题是useEffect内部是否必须发生清除间隔。在我的示例中,我不是在 useEffect 内部而是在功能组件的主体中清除间隔。它们对我的方法有什么缺点吗?
    • 组件会因为多种原因而频繁更新,每次更新时,您的if (!count) 都会被调用。所以最好使用useEffect
    【解决方案2】:

    setInterval是一个function,它被重复执行,它返回一个间隔的id。当您使用此 ID 调用 clearInterval 时,您会阻止 function 重复。不是必须在某个function 内执行此操作,当您不再希望随后调用该function 时需要清除它。你可以在function 中调用它作为useEffect 的结果,如果这是你需要的话。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-25
      • 2019-12-03
      • 1970-01-01
      • 2021-04-07
      相关资源
      最近更新 更多