Skip to content

Commit

Permalink
fix: preload request should be consumed within revalidate to suppor…
Browse files Browse the repository at this point in the history
…t `parallel` option (#2727)

* fix: preload request should be consumed within revalidate.

* adjust order

* update test comment
  • Loading branch information
promer94 authored Jul 31, 2023
1 parent bf1cd03 commit d1b7169
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 15 deletions.
26 changes: 11 additions & 15 deletions infinite/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,22 +169,8 @@ export const infinite = (<Data, Error>(useSWRNext: SWRHook) =>
SWRInfiniteCacheValue<Data, any>
>(cache, pageKey)

const hasPreloadedRequest = pageKey in PRELOAD
// Get the cached page data.
let pageData = getSWRCache().data as Data

if (hasPreloadedRequest) {
const req = PRELOAD[pageKey]
// delete the preload cache key before resolving it
// in case there's an error
delete PRELOAD[pageKey]
// get the page data from the preload cache
pageData = await req
// set the SWR cache with the preloaded data
setSWRCache({ data: pageData, _k: pageArg })
// remove the preload cache key to prevent memory leak
}

// should fetch (or revalidate) if:
// - `revalidateAll` is enabled
// - `mutate()` called
Expand All @@ -203,7 +189,17 @@ export const infinite = (<Data, Error>(useSWRNext: SWRHook) =>
!config.compare(cacheData[i], pageData))
if (fn && shouldFetchPage) {
const revalidate = async () => {
pageData = await fn(pageArg)
const hasPreloadedRequest = pageKey in PRELOAD
if (!hasPreloadedRequest) {
pageData = await fn(pageArg)
} else {
const req = PRELOAD[pageKey]
// delete the preload cache key before resolving it
// in case there's an error
delete PRELOAD[pageKey]
// get the page data from the preload cache
pageData = await req
}
setSWRCache({ data: pageData, _k: pageArg })
data[i] = pageData
}
Expand Down
45 changes: 45 additions & 0 deletions test/use-swr-infinite-preload.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -251,4 +251,49 @@ describe('useSWRInfinite - preload', () => {
preload(() => getKey(0), fetcher)
expect(calledWith).toBe(getKey(0))
})
it('should not break parallel option', async () => {
// mock api
const pageData = ['apple', 'banana', 'pineapple']

const key = createKey()
const fetcher = ([_, index]) =>
createResponse(`${pageData[index]}, `, { delay: index === 0 ? 50 : 200 })
function Page() {
const { data } = useSWRInfinite(index => [key, index], fetcher, {
initialSize: 3,
parallel: true
})

return <div>data:{data}</div>
}
preload([key, 0], fetcher)
renderWithConfig(<Page />)
screen.getByText('data:')
// If SWR sends parallel requests, it should only take 200ms
await act(() => sleep(200))
screen.getByText('data:apple, banana, pineapple,')
})
it('should be able to preload multiple page', async () => {
// mock api
const pageData = ['apple', 'banana', 'pineapple']

const key = createKey()
const fetcher = ([_, index]) =>
createResponse(`${pageData[index]}, `, { delay: 50 })
function Page() {
const { data } = useSWRInfinite(index => [key, index], fetcher, {
initialSize: 3,
parallel: true
})

return <div>data:{data}</div>
}
preload([key, 0], fetcher)
preload([key, 1], fetcher)
preload([key, 2], fetcher)
renderWithConfig(<Page />)
screen.getByText('data:')
await act(() => sleep(50))
screen.getByText('data:apple, banana, pineapple,')
})
})

0 comments on commit d1b7169

Please sign in to comment.