React挂钩-清除超时和间隔的正确方法 [英] React hooks - right way to clear timeouts and intervals

查看:60
本文介绍了React挂钩-清除超时和间隔的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白为什么当我使用setTimeout函数时,我的react组件开始进入无限console.log.一切正常,但PC开始陷入困境. 有人说超时中的功能会更改我的状态,并会重新渲染组件,设置新的计时器等.现在,我需要了解如何清除它.

I don't understand why is when I use setTimeout function my react component start to infinite console.log. Everything is working, but PC start to lag as hell. Some people saying that function in timeout changing my state and that rerender component, that sets new timer and so on. Now I need to understand how to clear it's right.

export default function Loading() {
  // if data fetching is slow, after 1 sec i will show some loading animation
  const [showLoading, setShowLoading] = useState(true)
  let timer1 = setTimeout(() => setShowLoading(true), 1000)

  console.log('this message will render  every second')
  return 1
}

清除不同版本的代码无济于事:

Clear in different version of code not helping to:

const [showLoading, setShowLoading] = useState(true)
  let timer1 = setTimeout(() => setShowLoading(true), 1000)
  useEffect(
    () => {
      return () => {
        clearTimeout(timer1)
      }
    },
    [showLoading]
  )

每次运行useEffect时,useEffect中的

推荐答案

Return 函数都会运行(第一次运行是在组件安装时除外).考虑一下它,因为每次执行新的useEffect执行时,旧的执行都会被删除.

Return function in useEffect runs every time useEffect runs (except first run on component mount). Think about it as every time there is new useEffect execution, the old one get deleted.

export default function Loading() {   
     const [showLoading, setShowLoading] = useState(false)
      
     useEffect(
        () => {
          let timer1 = setTimeout(() => setShowLoading(null), 1000)
    
          // this will clear Timeout when component unmount like in willComponentUnmount
          return () => {
            clearTimeout(timer1)
          }
        },
        [] //useEffect will run only one time
           //if you pass a value to array, like this [data] than clearTimeout will run every time this value changes (useEffect re-run)
      )

 return showLoading && <div>I will be visible after ~1000ms</div>
}

如果您需要清除超时时间或间隔时间不在某处:

export default function Loading() {   
     const [showLoading, setShowLoading] = useState(false)
      
     const timerToClearSomewhere = useRef(null) //now you can pass timer to another component

     useEffect(
        () => {
          timerToClearSomewhere.current = setInterval(() => setShowLoading(true), 50000)
    
          return () => {
            clearInterval(timerToClearSomewhere.current)
          }
        },
        []
      )

  //here we can imitate clear from somewhere else place
  useEffect(() => {
    setTimeout(() => clearInterval(timerToClearSomewhere.current), 1000)
  }, [])

 return showLoading ? <div>I will never be visible because interval was cleared</div> : <div>showLoading is false</div>
}

丹·阿布拉莫夫的文章.

这篇关于React挂钩-清除超时和间隔的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆