I have a hook that use useInfiniteQuery:
const useGetData = (page: number = 1) => {
return useInfiniteQuery({
queryKey: ["data"],
queryFn: () => getAllData(page),
getPreviousPageParam: (firstPage) => firstPage.previousId ?? undefined,
getNextPageParam: (lastPage) => lastPage.nextId ?? undefined,
});
};
Data fetching is:
export const getAllData = async (page: number) => {
return (await axios.get(`data?pageSize=15&pageNumber=${page}`)).data;
}
I want to return axios response typed like this:
return (await axios.get<Data[]>(`data?pageSize=15&pageNumber=${page}`)).data;
But when I do this I am getting typescript error in hook:
getPreviousPageParam: (firstPage) => firstPage.previousId ?? undefined,
getNextPageParam: (lastPage) => lastPage.nextId ?? undefined,
That previousId and nextId doesn't exist on type Data[]. What should I do to fix this typescript error?
I think there's a bit of a misunderstanding of how Infinite Queries work:
pageParam
value to the QueryFunction. You have to use it, because that's how you can differentiate between which page is currently fetching.getNextPageParam
.So if you fetch the first page, and it returns an Array of Data, as denoted by the type Data[]
, that is what gets passed to getNextPageParam
. Now you need to tell React Query what the next page is, depending on that information.
In our examples, we use a different structure: The server returns an object containing:
{
items: [{ id: 520, ... }, { id: 521, ... }, { id: 522, ... }],
nextId: 523
}
with that structure, it's straightforward to find out what the next page param should be: lastPage.nextId
.
If you have a different structure, you need to implement getNextPageParam
differently.
As it seems that you have a paginated approach rather than a cursor based approach, it's good to know that we also provide the list of all pages to the getNextPageParam
function. With that, you can say that the param for the next page is the length of the current pages plus one:
const useGetData = () => {
return useInfiniteQuery({
queryKey: ["data"],
queryFn: ({ pageParam }) => getAllData(pageParam),
initialPageParam: 1,
getNextPageParam: (lastPage, allPages) => allPages.length + 1
});
};
pageParam
will be 1
on the first fetch because of initialPageParam
.
After that, if you fetch the next page, we pass allPages
, which has a length of 1 then, to getNextPageParam
. For that, we return 2, so the second page will receive pageParam: 2
and can then fetch the second page. This will continue for the 3rd page, where allPages
will have a length of 2, so we compute 3 and so on.