From 087c17cc13a3d764c2d58261cbfe2f47537aece2 Mon Sep 17 00:00:00 2001 From: Yixuan Xu Date: Thu, 27 Jul 2023 04:01:17 +0800 Subject: [PATCH] fix: preload request should be consumed within revalidate. --- infinite/src/index.ts | 28 +++++++--------- test/use-swr-infinite-preload.test.tsx | 46 ++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/infinite/src/index.ts b/infinite/src/index.ts index 2b41b1c78..f2fed1454 100644 --- a/infinite/src/index.ts +++ b/infinite/src/index.ts @@ -169,22 +169,8 @@ export const infinite = ((useSWRNext: SWRHook) => SWRInfiniteCacheValue >(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 @@ -203,9 +189,19 @@ export const infinite = ((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) diff --git a/test/use-swr-infinite-preload.test.tsx b/test/use-swr-infinite-preload.test.tsx index c25d8fbc3..504bd567d 100644 --- a/test/use-swr-infinite-preload.test.tsx +++ b/test/use-swr-infinite-preload.test.tsx @@ -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
data:{data}
+ } + preload([key, 0], fetcher) + renderWithConfig() + 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
data:{data}
+ } + preload([key, 0], fetcher) + preload([key, 1], fetcher) + preload([key, 2], fetcher) + renderWithConfig() + screen.getByText('data:') + // If SWR sends requests sequentially, it takes 150ms at least + await act(() => sleep(50)) + screen.getByText('data:apple, banana, pineapple,') + }) })