diff --git a/README.md b/README.md index 1a2097dd3..ff1b482bb 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/src/config.ts b/src/config.ts index fc20b95ea..f395cf764 100644 --- a/src/config.ts +++ b/src/config.ts @@ -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 @@ -65,7 +64,9 @@ const defaultConfig: ConfigInterface = { refreshInterval: 0, revalidateOnFocus: true, + revalidateOnReconnect: true, refreshWhenHidden: false, + refreshWhenOffline: false, shouldRetryOnError: true, suspense: false } diff --git a/src/types.ts b/src/types.ts index 23c29b3d0..9a1487efa 100644 --- a/src/types.ts +++ b/src/types.ts @@ -13,7 +13,9 @@ export interface ConfigInterface< refreshInterval?: number refreshWhenHidden?: boolean + refreshWhenOffline?: boolean revalidateOnFocus?: boolean + revalidateOnReconnect?: boolean shouldRetryOnError?: boolean fetcher?: Fn suspense?: boolean diff --git a/src/use-swr.ts b/src/use-swr.ts index 0a373a390..9c9e510b1 100644 --- a/src/use-swr.ts +++ b/src/use-swr.ts @@ -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' @@ -459,7 +458,8 @@ function useSWR( 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 @@ -473,6 +473,12 @@ function useSWR( 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 @@ -502,6 +508,10 @@ function useSWR( if (timeout !== null) { clearTimeout(timeout) } + + if (reconnect !== null) { + removeEventListener('online', reconnect) + } } }, [key, config.refreshInterval, revalidate])