Home > Blockchain >  How to stop setInterval when tab is not active while using useEffect?
How to stop setInterval when tab is not active while using useEffect?

Time:08-10

I'm using setInterval in useEffect. When use not actively using tab, I't requesting like forever. It causing some memory issue. I have to, fetch data in every 3000ms, also stop it when user is not using this tab actively. How can I do such a thing?

I tried to use document.visibiltyState and I couldn't worked it.

My code:

useEffect(() => {
    try {
        const interval = setInterval(() => {
            getTransactionGroupStats()

            getTransactionGroups()

        }, 3000)

        getBinanceBalanceStats()

        return () => {
            clearInterval(interval)
        }
    } catch (error) {
        console.error(error)
    }
}, [])

CodePudding user response:

You can user event listener and listen to the event focus and blur. Focus when user is on that tab Blur when user navigate away from that tab.

useEffect(() => {
     let interval ;
        const unsubscribe = navigation.addListener('focus', () => {
          try {
            interval = setInterval(() => {
                getTransactionGroupStats()
    
                getTransactionGroups()
    
            }, 3000)
    
            getBinanceBalanceStats()
    
           
        } catch (error) {
            console.error(error)
        }
        });
        
        // if user navigate clean interval 
        navigation.addListener('blur', () => {
         clearInterval(interval)
        });
    
        // Return the function to unsubscribe from the event so it gets removed on unmount
        return unsubscribe;
      }, []);

CodePudding user response:

Another alternative and a little more scalable could be that you create a custom hook to see if the user is active or not and every time it changes you execute the useEffect

useActive.ts

export const useActive = (time: number) => {
    const [active, setActive] = useState(false)
    const timer: any = useRef()
    const events = ['keypress', 'mousemove', 'touchmove', 'click', 'scroll']

    useEffect(() => {
        const handleEvent = () => {
            setActive(true)
            if (timer.current) {
                window.clearTimeout(timer.current)
            }
            timer.current = window.setTimeout(() => {
                setActive(false)
            }, time)
        }

        events.forEach((event: string) => document.addEventListener(event, handleEvent))

        return () => {
            events.forEach((event: string) => document.removeEventListener(event, handleEvent))
        }
    }, [time])

    return active
}

YourApp.tsx

const active = useActive(3000)

useEffect(() => {
   if(active){
     try {
            const interval = setInterval(() => {
            getTransactionGroupStats()

            getTransactionGroups()

        }, 3000)

        getBinanceBalanceStats()

        return () => {
            clearInterval(interval)
        }
    } catch (error) {
        console.error(error)
    }

  }
}, [active])
  • Related