React hooks - right way to clear timeouts and intervals

后端 未结 6 792
感情败类
感情败类 2020-12-01 02:54

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.

6条回答
  •  無奈伤痛
    2020-12-01 03:04

    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.

    This is a working way to use and clear timeouts or intervals:

    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 && 
    I will be visible after ~1000ms
    }

    If you need to clear timeouts or intervals somewhere outside:

    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 ? 
    I will never be visible because interval was cleared
    :
    showLoading is false
    }

    Article from Dan Abramov.

提交回复
热议问题