Issue with Cache and Pagination in useInfiniteQuery #7511
-
DescriptionI am encountering an issue with caching and pagination using
CodeHere is the code snippet illustrating the issue: import {
InfiniteData,
useInfiniteQuery,
useQueryClient,
} from '@tanstack/react-query';
import queryString from 'query-string';
import { useEffect, useMemo } from 'react';
import { SupportTicketRoot, SupportTicketVariables } from '../../model';
import { NSupportTicket } from '../../model/support-ticket/types';
import normalizeSupportTicket from './normalizer';
type Dependencies = {
variables?: SupportTicketVariables;
};
export const getSupportTicket = async (
bodyParams?: string,
qs?: string
): Promise<SupportTicketRoot> => {
...
};
const useSupportTicket = (deps?: Dependencies) => {
const { variables } = deps || {};
const { pageSize = 20, pageIndex = 0, ...rest } = variables || {};
const queryClient = useQueryClient();
const queryCache = queryClient.getQueryCache();
const bodyParams = JSON.stringify(rest);
const qs = queryString.stringify({ pageIndex, pageSize }, { encode: false });
const cache = queryCache.find<InfiniteData<SupportTicketRoot>>({
queryKey: ['support-tickets', bodyParams],
});
const pageParams = cache?.state.data?.pageParams;
const pages = cache?.state.data?.pages;
const {
data,
isPending,
isFetchingNextPage,
isFetchingPreviousPage,
error,
refetch,
fetchNextPage,
} = useInfiniteQuery<SupportTicketRoot>({
queryKey: ['support-tickets', bodyParams],
queryFn: () => getSupportTicket(bodyParams, qs),
initialPageParam: pageIndex,
getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => {
if ((lastPage.data || []).length < pageSize) {
return undefined;
}
console.log({ lastPage, allPages, lastPageParam, allPageParams });
return ((lastPageParam as number) || 0) + 1;
},
});
useEffect(() => {
if (pageParams && !pageParams.includes(pageIndex)) {
fetchNextPage();
}
}, [fetchNextPage, pageIndex, pageParams]);
return useMemo(() => {
const normalized = (data?.pages || []).reduce(
(acc: NSupportTicket[], curr) => {
if (!curr.data) return acc;
acc.push(...normalizeSupportTicket(curr));
return acc;
},
[]
);
return {
data: normalized,
loading: isPending || isFetchingNextPage || isFetchingPreviousPage,
error,
refetch,
};
}, [
data,
isPending,
isFetchingNextPage,
isFetchingPreviousPage,
error,
refetch,
]);
};
export default useSupportTicket; IssueThe problem seems to stem from the cache behavior of useInfiniteQuery. When switching filters, the previous pages' data is being overwritten, causing the pagination to malfunction. Expected BehaviorWhen changing the filter, the cache should update correctly without overwriting the previous pages' data, allowing pagination to work as expected. Actual BehaviorChanging the filter causes all pages' data to be overwritten by the initial query's data, resulting in repetitive data on subsequent pages. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
the cache entries are overwriting each other because you use the same queryKey. Everything used inside the |
Beta Was this translation helpful? Give feedback.
the cache entries are overwriting each other because you use the same queryKey. Everything used inside the
queryFn
must be part of thequeryKey
. You are usingqs
in thequeryFn
, but it's not part of the key.