Skip to content

Infinite lists ​

Pass the three pagination fields. onEndReached fires once per page: it waits until the next page arrives or the user scrolls again, so you never get duplicate requests.

tsx
const query = useInfiniteQuery({
  queryKey: ['banks', term],
  queryFn: ({ pageParam }) => api.banks({ page: pageParam, search: term }),
  initialPageParam: 1,
  getNextPageParam: (last) => last.nextPage ?? undefined,
});

<ActionSheetPicker
  items={query.data?.pages.flatMap((page) => page.items) ?? []}
  schema={{ value: 'id', label: 'name' }}
  searchable={{ mode: 'remote', onChangeText: setTerm }}
  loading={query.isLoading}
  pagination={{
    hasMore: Boolean(query.hasNextPage),
    loadingMore: query.isFetchingNextPage,
    onEndReached: query.fetchNextPage,
  }}
  value={bankId}
  onChange={setBankId}
/>;
Remote search results on iOS
Remote search + infinite scroll
  • Duplicates removed. Items repeated across pages are de-duplicated by value.
  • Label survives paging. The selected label stays visible when the selected item is on a page that isn't loaded.
  • Loading states. loading shows a spinner while the first page loads; loadingMore shows one at the bottom of the list.
  • Edit forms: pass the saved item in selectedItems so its label shows before page 1 arrives.

Not using TanStack Query?

pagination only needs hasMore, loadingMore and onEndReached, so any data source works: RTK Query, SWR, Apollo or plain fetch.

Released under the MIT License.