useInfiniteQuery<TData, TError, TPageParam> function

UseInfiniteQueryResult<TData, TError, TPageParam> useInfiniteQuery<TData, TError, TPageParam>(
  1. RawQueryKey queryKey,
  2. InfiniteQueryFn<TData, TPageParam> queryFn, {
  3. required TPageParam initialPageParam,
  4. required TPageParam? getNextPageParam(
    1. TData,
    2. List<TData>,
    3. TPageParam,
    4. List<TPageParam>,
    ),
  5. TPageParam? getPreviousPageParam(
    1. TData,
    2. List<TData>,
    3. TPageParam,
    4. List<TPageParam>,
    )?,
  6. int? maxPages,
  7. bool enabled = true,
  8. RefetchOnMount? refetchOnMount,
  9. Duration? staleDuration,
  10. Duration? cacheDuration,
  11. Duration? refetchInterval,
  12. int? retryCount,
  13. Duration? retryDelay,
})

Used for infinite query. In addition to queryKey and queryFn, it requires an initialPageParam and getNextPageParam option. The query function receives the pageParam parameter that can be used to fetch the current page.

Returns a UseInfiniteQueryResult

Example:

final items = useInfiniteQuery<PageResult, Error, int>(
  ['infinity'],
  (page) => infinityAPI.get(page),
  initialPageParam: 1,
  getNextPageParam: ((lastPage, allPages, lastPageParam, allPageParam) {
    return lastPage.hasMore ? lastPage.page + 1 : null;
  }),
);

Implementation

UseInfiniteQueryResult<TData, TError, TPageParam>
    useInfiniteQuery<TData, TError, TPageParam>(
  RawQueryKey queryKey,
  InfiniteQueryFn<TData, TPageParam> queryFn, {
  required TPageParam initialPageParam,
  required TPageParam? Function(
    TData,
    List<TData>,
    TPageParam,
    List<TPageParam>,
  ) getNextPageParam,
  TPageParam? Function(
    TData,
    List<TData>,
    TPageParam,
    List<TPageParam>,
  )? getPreviousPageParam,
  int? maxPages,
  bool enabled = true,
  RefetchOnMount? refetchOnMount,
  Duration? staleDuration,
  Duration? cacheDuration,
  Duration? refetchInterval,
  int? retryCount,
  Duration? retryDelay,
}) {
  final options = useMemoized(
    () => UseInfiniteQueryOptions<TData, TError, TPageParam>(
      initialPageParam: initialPageParam,
      getNextPageParam: getNextPageParam,
      getPreviousPageParam: getPreviousPageParam,
      maxPages: maxPages,
      enabled: enabled,
      refetchOnMount: refetchOnMount,
      staleDuration: staleDuration,
      cacheDuration: cacheDuration,
      refetchInterval: refetchInterval,
      retryCount: retryCount,
      retryDelay: retryDelay,
    ),
    [
      initialPageParam,
      getNextPageParam,
      getPreviousPageParam,
      maxPages,
      enabled,
      refetchOnMount,
      staleDuration,
      cacheDuration,
      refetchInterval,
      retryCount,
      retryDelay,
    ],
  );
  final client = useQueryClient();
  final observer = useMemoized(
    () => InfiniteQueryObserver<TData, TError, TPageParam>(
      queryKey,
      queryFn,
      client: client,
      options: options,
    ),
    [QueryKey(queryKey)],
  );

  // This subscribes to the observer
  // and rebuilds the widgets on updates.
  useListenable(observer);

  useEffect(() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      observer.updateOptions(options);
    });
    return null;
  }, [observer, options]);

  useEffect(() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      observer.initialize();
    });
    return () {
      observer.destroy();
    };
  }, [observer]);

  final isFetchingNextPage = observer.query.state.isFetching &&
      observer.query.state.fetchMeta?.direction == FetchDirection.forward;
  final isFetchingPreviousPage = observer.query.state.isFetching &&
      observer.query.state.fetchMeta?.direction == FetchDirection.backward;

  final isFetchNextPageError = observer.query.state.isError &&
      observer.query.state.fetchMeta?.direction == FetchDirection.forward;
  final isFetchPreviousPageError = observer.query.state.isError &&
      observer.query.state.fetchMeta?.direction == FetchDirection.backward;

  late final bool hasNextPage;
  late final bool hasPreviousPage;
  final data = observer.query.state.data;

  if (data == null) {
    hasNextPage = false;
    hasPreviousPage = false;
  } else {
    final pages = data.pages;
    final firstPage = pages.first;
    final lastPage = pages.last;
    final pageParams = data.pageParams;
    final firstPageParam = pageParams.last;
    final lastPageParam = pageParams.last;

    final nextPageParam = options.getNextPageParam(
      lastPage,
      pages,
      lastPageParam,
      pageParams,
    );

    final previousPageParam = options.getNextPageParam(
      firstPage,
      pages,
      firstPageParam,
      pageParams,
    );

    hasNextPage = nextPageParam != null;
    hasPreviousPage = previousPageParam != null;
  }

  return UseInfiniteQueryResult(
    fetchNextPage: observer.fetchNextPage,
    fetchPreviousPage: observer.fetchPreviousPage,
    isFetchingNextPage: isFetchingNextPage,
    isFetchingPreviousPage: isFetchingPreviousPage,
    hasNextPage: hasNextPage,
    hasPreviousPage: hasPreviousPage,
    isRefetching: observer.query.state.isFetching &&
        !isFetchingNextPage &&
        !isFetchingPreviousPage,
    data: observer.query.state.data,
    dataUpdatedAt: observer.query.state.dataUpdatedAt,
    error: observer.query.state.error,
    errorUpdatedAt: observer.query.state.errorUpdatedAt,
    isError: observer.query.state.isError,
    isLoading: observer.query.state.isLoading,
    isFetching: observer.query.state.isFetching,
    isSuccess: observer.query.state.isSuccess,
    status: observer.query.state.status,
    isFetchNextPageError: isFetchNextPageError,
    isFetchPreviousPageError: isFetchPreviousPageError,
    isInvalidated: observer.query.state.isInvalidated,
    isRefetchError: observer.query.state.isRefetchError,
  );
}