繁体   English   中英

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

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

我在setInterval中使用useEffect 当使用不主动使用标签时,我不会要求永远。 它导致一些 memory 问题。 我必须每3000ms获取一次数据,当用户不主动使用此选项卡时也要停止它。 我怎么能做这样的事情?

我尝试使用document.visibiltyState但无法使用。

我的代码:

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

            getTransactionGroups()

        }, 3000)

        getBinanceBalanceStats()

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

您可以用户事件侦听器并侦听事件焦点和模糊。 当用户在该选项卡上时聚焦当用户离开该选项卡时模糊

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

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