0

In my react-native application I use react-query to fetch the data from backend written in Spring Boot.

export function useFetchAllNotes(kindeId: string) {
    return useInfiniteQuery<ApiResponseListNote, AxiosError, Response>({
            initialPageParam: 0,
            queryKey: ['userNotes', {kindeId}],
            queryFn: ({pageParam = 0}) => fetchNotesForUser(kindeId, pageParam as number),
            getNextPageParam: (lastPage) => {
                const currentPage = lastPage.metadata.paging?.page as number;
                const totalPages = lastPage.metadata.paging?.totalPages as number;
                return currentPage < totalPages - 1
                    ? currentPage + 1
                    : undefined;
            },
            select: (data) => {
                return {
                    pages: data.pages.flatMap((page) => page.data ?? []),
                    pageParams: data.pageParams,
                };
            }
        }
    );
}

the spring boot endpoint looks like this

    @GetMapping("/{kindeId}")
    fun getUserNotes(
        @PageableDefault(sort = ["createdAt"], direction = Sort.Direction.DESC, size = 10)
        pageable: Pageable,
        @PathVariable kindeId: String
    ): ApiResponse<List<Note>> = noteService.getAllUserNotes(kindeId, pageable)

which returns object with metadata containing pagination object like this

export interface ApiResponsePaging {
    'totalPages': number;
    'totalElements': number;
    'page': number;
    'pageSize': number;
}

all the values above are just values taken from Pageable in spring boot, so page indexing starts from 0

And the FlatList where the query is used


const {
    data: notes,
    isLoading: isFetchingNotes,
    error: fetchingNotesError,
    refetch: refetchNotes,
    isRefetching: isRefetchingNotes,
    hasNextPage,
    fetchNextPage,
    isFetchingNextPage
} = useFetchAllNotes(kindeId)

const loadMore = () => {
    if (hasNextPage) {
       fetchNextPage();
    }
};

<FlatList
    data={notes?.pages ?? [] as Note[]}
    renderItem={renderItem}
    keyExtractor={(_, index) => index.toString()}
    numColumns={1}
    onEndReached={({ distanceFromEnd }) => {
      if (distanceFromEnd < 0) return;
      loadMore()
    }}
    onEndReachedThreshold={0.1}
    initialNumToRender={10}
/>

The problem is that when I reach the last page scrolling, then it starts fetching data from 0th page again and again. Do I miss something?

1
  • Try to add console.log in getNextPageParam to see what it's return on end reached Commented Mar 31, 2024 at 13:45

1 Answer 1

0

I solved the problem by creating a store and saving the downloaded data and pagination in the store. Then, each time a new page is downloaded, I update the store and if I reach the last page, I disable the loading of more data

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.