简体   繁体   English

使用useEffect时标签不活动时如何停止setInterval?

[英]How to stop setInterval when tab is not active while using useEffect?

I'm using setInterval in useEffect .我在setInterval中使用useEffect When use not actively using tab, I't requesting like forever.当使用不主动使用标签时,我不会要求永远。 It causing some memory issue.它导致一些 memory 问题。 I have to, fetch data in every 3000ms , also stop it when user is not using this tab actively.我必须每3000ms获取一次数据,当用户不主动使用此选项卡时也要停止它。 How can I do such a thing?我怎么能做这样的事情?

I tried to use document.visibiltyState and I couldn't worked it.我尝试使用document.visibiltyState但无法使用。

My code:我的代码:

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

            getTransactionGroups()

        }, 3000)

        getBinanceBalanceStats()

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

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;
      }, []);

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另一种选择并且更具可扩展性可能是您创建一个自定义挂钩以查看用户是否处于活动状态,并且每次更改时您都执行 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])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM