Skip to content

Commit

Permalink
fix: preload request should be consumed within revalidate.
Browse files Browse the repository at this point in the history
  • Loading branch information
promer94 committed Jul 26, 2023
1 parent bf1cd03 commit 087c17c
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 16 deletions.
28 changes: 12 additions & 16 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,9 +189,19 @@ export const infinite = (<Data, Error>(useSWRNext: SWRHook) =>
!config.compare(cacheData[i], pageData))
if (fn && shouldFetchPage) {
const revalidate = async () => {
pageData = await fn(pageArg)
setSWRCache({ data: pageData, _k: 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
}
data[i] = pageData
setSWRCache({ data: pageData, _k: pageArg })
}
if (parallel) {
revalidators.push(revalidate)
Expand Down
46 changes: 46 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,50 @@ 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 requests sequentially, it takes 150ms at least
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:')
// If SWR sends requests sequentially, it takes 150ms at least
await act(() => sleep(50))
screen.getByText('data:apple, banana, pineapple,')
})
})

0 comments on commit 087c17c

Please sign in to comment.