Skip to content

Commit 8a4ff3a

Browse files
authored
Rework infinite query forced checks (#4854)
1 parent 36f1f64 commit 8a4ff3a

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

packages/toolkit/src/query/core/buildThunks.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -633,12 +633,19 @@ export function buildThunks<
633633
getState(),
634634
arg.queryCacheKey,
635635
)?.data as InfiniteData<unknown, unknown> | undefined
636-
// Don't want to use `isForcedQuery` here, because that
637-
// includes `refetchOnMountOrArgChange`.
636+
637+
// When the arg changes or the user forces a refetch,
638+
// we don't include the `direction` flag. This lets us distinguish
639+
// between actually refetching with a forced query, vs just fetching
640+
// the next page.
641+
const isForcedQueryNeedingRefetch = // arg.forceRefetch
642+
isForcedQuery(arg, getState()) &&
643+
!(arg as InfiniteQueryThunkArg<any>).direction
638644
const existingData = (
639-
arg.forceRefetch || !cachedData ? blankData : cachedData
645+
isForcedQueryNeedingRefetch || !cachedData ? blankData : cachedData
640646
) as InfiniteData<unknown, unknown>
641647

648+
642649
// If the thunk specified a direction and we do have at least one page,
643650
// fetch the next or previous page
644651
if ('direction' in arg && arg.direction && existingData.pages.length) {

packages/toolkit/src/query/tests/infiniteQueries.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ describe('Infinite queries', () => {
3737
}
3838

3939
let counters: Record<string, number> = {}
40+
let queryCounter = 0
4041

4142
const pokemonApi = createApi({
4243
baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' }),
@@ -149,6 +150,7 @@ describe('Infinite queries', () => {
149150
const url = new URL(request.url)
150151
const pageString = url.searchParams.get('page')
151152
const pageNum = parseInt(pageString || '0')
153+
queryCounter++
152154

153155
const results: Pokemon[] = [
154156
{ id: `${pageNum}`, name: `Pokemon ${pageNum}` },
@@ -168,6 +170,7 @@ describe('Infinite queries', () => {
168170
counters = {}
169171

170172
hitCounter = 0
173+
queryCounter = 0
171174

172175
process.env.NODE_ENV = 'development'
173176
})
@@ -697,6 +700,44 @@ describe('Infinite queries', () => {
697700
[{ id: '0', name: 'Pokemon 0' }],
698701
[{ id: '1', name: 'Pokemon 1' }],
699702
])
703+
704+
expect(queryCounter).toBe(2)
705+
706+
const entry2InitialLoad = await storeRef.store.dispatch(
707+
pokemonApiWithRefetch.endpoints.getInfinitePokemon.initiate('water', {}),
708+
)
709+
710+
checkResultData(entry2InitialLoad, [[{ id: '0', name: 'Pokemon 0' }]])
711+
712+
expect(queryCounter).toBe(3)
713+
714+
const entry2SecondPage = await storeRef.store.dispatch(
715+
pokemonApiWithRefetch.endpoints.getInfinitePokemon.initiate('water', {
716+
direction: 'forward',
717+
}),
718+
)
719+
checkResultData(entry2SecondPage, [
720+
[{ id: '0', name: 'Pokemon 0' }],
721+
[{ id: '1', name: 'Pokemon 1' }],
722+
])
723+
724+
expect(queryCounter).toBe(4)
725+
726+
// Should now be able to switch back to the first query.
727+
// The hooks dispatch on arg change without a direction.
728+
// That should trigger a refetch of the first query, meaning two requests.
729+
// It should also _replace_ the existing results, rather than appending
730+
// duplicate entries ([0, 1, 0, 1])
731+
const entry1Refetched = await storeRef.store.dispatch(
732+
pokemonApiWithRefetch.endpoints.getInfinitePokemon.initiate('fire', {}),
733+
)
734+
735+
checkResultData(entry1Refetched, [
736+
[{ id: '0', name: 'Pokemon 0' }],
737+
[{ id: '1', name: 'Pokemon 1' }],
738+
])
739+
740+
expect(queryCounter).toBe(6)
700741
})
701742

702743
test('Works with cache manipulation utils', async () => {

0 commit comments

Comments
 (0)