import { useState , useRef , useEffect } from 'react' ; import useEventListener from './useEventListener' ; function useVisibilityChange ( ) { const isVisibilityStateVisible = ( ) => document . visibilityState === 'visible' ; const [ isVisible , setIsVisible ] = useState ( true ) ; useEffect ( ( ) => { setIsVisible ( isVisibilityStateVisible ) ; } , [ ] ) ; useEventListener ( 'visibilitychange' , ( ) => { setIsVisible ( isVisibilityStateVisible ) ; } ) ; return isVisible ; } type OnPoll = ( ) => void ; interface PollerOptions { default interval ? : number ; default immediate ? : boolean ; default enabled ? : boolean ; } export default function usePoller ( onPoll , { interval = 30e3 , immediate = true , enabled = true } = { } ) { const savedCallback = useRef < OnPoll > ( ) ; const isVisible = useVisibilityChange ( ) ; const isPolling = isVisible && enabled ; useEffect ( ( ) => { savedCallback . current = onPoll ; } ) ; useEffect ( ( ) => { if ( ! isPolling ) { return ; } let id ; function scheduleNextPoll ( ) { unscheduleNextPoll ( ) ; id = setTimeout ( poll , interval ) ; } function unscheduleNextPoll ( ) { clearTimeout ( id ) ; } function poll ( ) { Promise . resolve ( savedCallback . current ?. ( ) ) . finally ( scheduleNextPoll ) ; } if ( immediate ) { poll ( ) ; } else { scheduleNextPoll ( ) ; } return unscheduleNextPoll ; } , [ interval , immediate , isPolling ] ) ; }