Skip to content

Commit

Permalink
Add isFallback state (#1925)
Browse files Browse the repository at this point in the history
* add isFallback

* remove -m

* add test case
  • Loading branch information
shuding committed Apr 15, 2022
1 parent 2564501 commit 2af00e9
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 23 deletions.
9 changes: 6 additions & 3 deletions infinite/index.ts
Expand Up @@ -258,14 +258,17 @@ export const infinite = (<Data, Error>(useSWRNext: SWRHook) =>
size: resolvePageSize(),
setSize,
mutate,
get error() {
return swr.error
},
get data() {
return swr.data
},
get error() {
return swr.error
},
get isValidating() {
return swr.isValidating
},
get isFallback() {
return swr.isFallback
}
} as SWRInfiniteResponse<Data, Error>
}) as unknown as Middleware
Expand Down
5 changes: 3 additions & 2 deletions src/types.ts
Expand Up @@ -216,10 +216,11 @@ export type SWRConfiguration<
> = Partial<PublicConfiguration<Data, Error, Fn>>

export interface SWRResponse<Data = any, Error = any> {
data?: Data
error?: Error
data: Data | undefined
error: Error | undefined
mutate: KeyedMutator<Data>
isValidating: boolean
isFallback: boolean
}

export type KeyLoader<Args extends Arguments = Arguments> =
Expand Down
40 changes: 27 additions & 13 deletions src/use-swr.ts
Expand Up @@ -307,30 +307,38 @@ export const useSWRHandler = <Data = any, Error = any>(
} catch (err) {
cleanupState()

const currentConfig = getConfig()
const { shouldRetryOnError } = currentConfig

// Not paused, we continue handling the error. Otherwise discard it.
if (!getConfig().isPaused()) {
if (!currentConfig.isPaused()) {
// Get a new error, don't use deep comparison for errors.
set({ error: err })
newState.error = err as Error

// Error event and retry logic. Only for the actual request, not
// deduped ones.
if (shouldStartNewRequest && isCurrentKeyMounted()) {
getConfig().onError(err, key, config)
currentConfig.onError(err, key, currentConfig)
if (
(typeof config.shouldRetryOnError === 'boolean' &&
config.shouldRetryOnError) ||
(isFunction(config.shouldRetryOnError) &&
config.shouldRetryOnError(err as Error))
shouldRetryOnError === true ||
(isFunction(shouldRetryOnError) &&
shouldRetryOnError(err as Error))
) {
// When retrying, dedupe is always enabled
if (isActive()) {
// If it's active, stop. It will auto revalidate when refocusing
// or reconnecting.
getConfig().onErrorRetry(err, key, config, revalidate, {
retryCount: (opts.retryCount || 0) + 1,
dedupe: true
})
// If it's inactive, stop. It will auto revalidate when
// refocusing or reconnecting.
// When retrying, deduplication is always enabled.
currentConfig.onErrorRetry(
err,
key,
currentConfig,
revalidate,
{
retryCount: (opts.retryCount || 0) + 1,
dedupe: true
}
)
}
}
}
Expand Down Expand Up @@ -546,6 +554,12 @@ export const useSWRHandler = <Data = any, Error = any>(
get isValidating() {
stateDependencies.isValidating = true
return isValidating
},
get isFallback() {
stateDependencies.data = true
// `isFallback` is only true when we are displaying a value other than
// the cached one.
return data !== cachedData
}
} as SWRResponse<Data, Error>
}
Expand Down
12 changes: 8 additions & 4 deletions test/use-swr-cache.test.tsx
Expand Up @@ -198,19 +198,23 @@ describe('useSWR - cache provider', () => {
it('should support fallback values with custom provider', async () => {
const key = createKey()
function Page() {
const { data } = useSWR(key, async () => {
const { data, isFallback } = useSWR(key, async () => {
await sleep(10)
return 'data'
})
return <>{String(data)}</>
return (
<>
{String(data)},{String(isFallback)}
</>
)
}

renderWithConfig(<Page />, {
provider: () => provider,
fallback: { [key]: 'fallback' }
})
screen.getByText('fallback') // no `undefined`, directly fallback
await screen.findByText('data')
screen.getByText('fallback,true') // no `undefined`, directly fallback
await screen.findByText('data,false')
})

it('should not return the fallback if cached', async () => {
Expand Down
2 changes: 1 addition & 1 deletion test/use-swr-loading.test.tsx
Expand Up @@ -138,7 +138,7 @@ describe('useSWR - loading', () => {
}

renderWithConfig(<Page />)
screen.getByText('data,error,isValidating,mutate')
screen.getByText('data,error,isFallback,isValidating,mutate')
})

it('should sync loading states', async () => {
Expand Down

0 comments on commit 2af00e9

Please sign in to comment.