Skip to content

Commit

Permalink
Prevent polling when browser is offline (#203)
Browse files Browse the repository at this point in the history
* Prevent polling when browser is offline

* Add online config options, update README

* Remove console.log statement

* Add comment

* Undo extraneous README changes

* Resolve suggested changes from @quietshu
  • Loading branch information
daneden authored and shuding committed Dec 18, 2019
1 parent 43f5fa6 commit 0cc1a56
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 30 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,10 @@ const { data, error, isValidating, revalidate } = useSWR(key, fetcher, options)
- `fetcher = undefined`: the default fetcher function
- `initialData`: initial data to be returned (note: This is per-hook)
- `revalidateOnFocus = true`: auto revalidate when window gets focused
- `revalidateOnReconnect = true`: automatically revalidate when the browser regains a network connection (via `navigator.onLine`)
- `refreshInterval = 0`: polling interval (disabled by default)
- `refreshWhenHidden = false`: polling when the window is invisible (if `refreshInterval` is enabled)
- `refreshWhenOffline = false`: polling when the browser is offline (determined by `navigator.onLine`)
- `shouldRetryOnError = true`: retry when fetcher has an error [(details)](#error-retries)
- `dedupingInterval = 2000`: dedupe requests with the same key in this time span
- `focusThrottleInterval = 5000`: only revalidate once during a time span
Expand Down
7 changes: 4 additions & 3 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import isDocumentVisible from './libs/is-document-visible'
import isOnline from './libs/is-online'

import {
ConfigInterface,
revalidateType,
RevalidateOptionInterface
RevalidateOptionInterface,
revalidateType
} from './types'

// Cache
Expand Down Expand Up @@ -65,7 +64,9 @@ const defaultConfig: ConfigInterface = {

refreshInterval: 0,
revalidateOnFocus: true,
revalidateOnReconnect: true,
refreshWhenHidden: false,
refreshWhenOffline: false,
shouldRetryOnError: true,
suspense: false
}
Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ export interface ConfigInterface<

refreshInterval?: number
refreshWhenHidden?: boolean
refreshWhenOffline?: boolean
revalidateOnFocus?: boolean
revalidateOnReconnect?: boolean
shouldRetryOnError?: boolean
fetcher?: Fn
suspense?: boolean
Expand Down
64 changes: 37 additions & 27 deletions src/use-swr.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,39 @@
import deepEqual from 'fast-deep-equal'
import {
useCallback,
useContext,
useEffect,
useLayoutEffect,
useRef,
useContext,
useCallback,
useReducer
useReducer,
useRef
} from 'react'
import deepEqual from 'fast-deep-equal'

import {
keyInterface,
ConfigInterface,
RevalidateOptionInterface,
updaterInterface,
triggerInterface,
mutateInterface,
broadcastStateInterface,
responseInterface,
fetcherFn,
reducerType,
actionType
} from './types'

import defaultConfig, {
cacheGet,
cacheSet,
CACHE_REVALIDATORS,
CONCURRENT_PROMISES,
CONCURRENT_PROMISES_TS,
FOCUS_REVALIDATORS,
CACHE_REVALIDATORS,
MUTATION_TS,
cacheGet,
cacheSet
MUTATION_TS
} from './config'
import SWRConfigContext from './swr-config-context'
import hash from './libs/hash'
import isDocumentVisible from './libs/is-document-visible'
import isOnline from './libs/is-online'
import throttle from './libs/throttle'
import hash from './libs/hash'
import SWRConfigContext from './swr-config-context'
import {
actionType,
broadcastStateInterface,
ConfigInterface,
fetcherFn,
keyInterface,
mutateInterface,
reducerType,
responseInterface,
RevalidateOptionInterface,
triggerInterface,
updaterInterface
} from './types'

const IS_SERVER = typeof window === 'undefined'

Expand Down Expand Up @@ -459,7 +458,8 @@ function useSWR<Data = any, Error = any>(
const tick = async () => {
if (
!errorRef.current &&
(config.refreshWhenHidden || isDocumentVisible())
(config.refreshWhenHidden || isDocumentVisible()) &&
(!config.refreshWhenOffline && isOnline())
) {
// only revalidate when the page is visible
// if API request errored, we stop polling in this round
Expand All @@ -473,6 +473,12 @@ function useSWR<Data = any, Error = any>(
timeout = setTimeout(tick, config.refreshInterval)
}

// set up reconnecting when the browser regains network connection
let reconnect = null
if (config.revalidateOnReconnect) {
reconnect = addEventListener('online', softRevalidate)
}

return () => {
// cleanup
dispatch = () => null
Expand Down Expand Up @@ -502,6 +508,10 @@ function useSWR<Data = any, Error = any>(
if (timeout !== null) {
clearTimeout(timeout)
}

if (reconnect !== null) {
removeEventListener('online', reconnect)
}
}
}, [key, config.refreshInterval, revalidate])

Expand Down

0 comments on commit 0cc1a56

Please sign in to comment.