Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix useSWRInfinite doesn't revalidate the first page #1301

Merged
merged 1 commit into from
Jul 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 3 additions & 6 deletions infinite/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export const infinite = ((<Data, Error>(useSWRNext: SWRHook) => (
const data: Data[] = []

const pageSize = resolvePageSize()

let previousPageData = null
for (let i = 0; i < pageSize; ++i) {
const [pageKey, pageArgs] = serialize(
Expand All @@ -129,15 +130,11 @@ export const infinite = ((<Data, Error>(useSWRNext: SWRHook) => (
revalidateAll ||
force ||
isUndefined(pageData) ||
(isUndefined(force) && i === 0 && !isUndefined(dataRef.current)) ||
(i === 0 && !isUndefined(dataRef.current)) ||
(originalData && !config.compare(originalData[i], pageData))

if (fn && shouldFetchPage) {
if (pageArgs !== null) {
pageData = await fn(...pageArgs)
} else {
pageData = await fn(pageKey)
}
pageData = await fn(...pageArgs)
cache.set(pageKey, pageData)
}

Expand Down
4 changes: 3 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ module.exports = {
modulePathIgnorePatterns: ['<rootDir>/examples/'],
setupFilesAfterEnv: ['<rootDir>/jest-setup.ts'],
moduleNameMapper: {
'^swr$': '<rootDir>/src'
'^swr$': '<rootDir>/src',
'^swr/infinite$': '<rootDir>/infinite/index.ts',
'^swr/immutable$': '<rootDir>/immutable/index.ts'
},
globals: {
'ts-jest': {
Expand Down
49 changes: 45 additions & 4 deletions test/use-swr-infinite.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'
import { render, fireEvent, act, screen } from '@testing-library/react'
import { mutate, createCache, SWRConfig } from 'swr'
import useSWRInfinite, { getInfiniteKey } from 'swr/infinite'
import { sleep, createResponse } from './utils'
import { sleep, createKey, createResponse } from './utils'

describe('useSWRInfinite', () => {
it('should render the first page component', async () => {
Expand Down Expand Up @@ -154,9 +154,11 @@ describe('useSWRInfinite', () => {

it('should skip fetching existing pages when loading more', async () => {
let requests = 0
const key = createKey()

function Page() {
const { data, size, setSize } = useSWRInfinite<string, string>(
index => [`pagetest-4`, index],
index => [key, index],
(_, index) => {
requests++
return createResponse(`page ${index}, `)
Expand Down Expand Up @@ -185,13 +187,13 @@ describe('useSWRInfinite', () => {
fireEvent.click(screen.getByText('data:page 0,'))

await screen.findByText('data:page 0, page 1,') // mounted
expect(requests).toEqual(2)
expect(requests).toEqual(3) // revalidate page 1, load page 2

// load next page
fireEvent.click(screen.getByText('data:page 0, page 1,'))

await screen.findByText('data:page 0, page 1, page 2,') // mounted
expect(requests).toEqual(3)
expect(requests).toEqual(5) // revalidate page 1, load page 3
})

it('should cache page count', async () => {
Expand Down Expand Up @@ -572,6 +574,7 @@ describe('useSWRInfinite', () => {
fireEvent.click(screen.getByText('data:'))
await screen.findByText('data:')
})

it('should mutate a cache with getInfiniteKey', async () => {
let count = 0
function Page() {
Expand Down Expand Up @@ -650,4 +653,42 @@ describe('useSWRInfinite', () => {

expect(loggedValues).toEqual([1])
})

// https://github.com/vercel/swr/issues/908
it('should revalidate first page after mutating', async () => {
let renderedData
const key = createKey()
let v = 'old'

function Page() {
const { data, size, mutate: boundMutate } = useSWRInfinite<
string,
string
>(i => [key, i], () => v)
renderedData = data

return (
<div>
<button
onClick={() => {
v = 'new'
boundMutate([v])
}}
>
mutate
</button>
<p>size=${size}</p>
</div>
)
}

render(<Page />)

await screen.findByText('mutate')
await act(() => sleep(1))
expect(renderedData).toEqual(['old'])
fireEvent.click(screen.getByText('mutate'))
await act(() => sleep(1))
expect(renderedData).toEqual(['new'])
})
})