useInfiniteQuery

Example

import {useInfiniteQuery} from "blitz"
import getProducts from "/app/products/queries/getProducts"
function Products(props) {
const [groupedProducts, {isFetching, isFetchingMore, fetchMore, canFetchMore}] = useInfiniteQuery(
getProducts,
(page = {take: 100, skip: 0}) => ({where: {storeId: props.storeId}, ...page}),
{
getFetchMore: (lastGroup, allGroups) => lastGroup.nextPage,
},
)
return (
<>
{groupedProducts.map((group, i) => (
<React.Fragment key={i}>
{group.products.map((product) => (
<p key={product.id}>{product.name}</p>
))}
</React.Fragment>
))}
<div>
<button onClick={() => fetchMore()} disabled={!canFetchMore || !!isFetchingMore}>
{isFetchingMore ? "Loading more..." : canFetchMore ? "Load More" : "Nothing more to load"}
</button>
</div>
<div>{isFetching && !isFetchingMore ? "Fetching..." : null}</div>
</>
)
}

And here's the query to work with that:

export default async function getProducts({where, orderBy, take, skip}: GetProductsInput) {
const products = await db.product.findMany({
where,
orderBy,
take,
skip,
})
const count = await db.product.count()
const hasMore = skip < count
const nextPage = hasMore ? {take, skip: skip + take} : null
return {
products,
nextPage,
}
}

API

const [
groupedQueryFunctionResults,
{
isFetching,
failureCount,
refetch,
fetchMore,
canFetchMore,
mutate,
}
] = useQuery(blitzQueryFunction, getQueryInputArguments, {
// options
getFetchMore: (lastPage, allPages) => pageOptions
manual,
enabled,
retry,
retryDelay,
staleTime
cacheTime,
refetchInterval,
refetchIntervalInBackground,
refetchOnWindowFocus,
onSuccess,
onError,
suspense,
initialData,
refetchOnMount,
})

Arguments

  • blitzQueryFunction: A Blitz query function
    • Required
  • getQueryInputArguments: (pageOptions) => queryInputArguments
    • Required
    • A function that accepts the current page options and returns the queryInputArguments
    • On the first page load, pageOptions is undefined.
    • For subsequent pages, pageOptions is whatever is returned from getFetchMore()
  • options
    • Optional

Options

  • getFetchMore: Function(lastPage, allPages) => pageOptions | Boolean
    • When new data is received for this query, this function receives both the last page of the infinite list of data and the full array of all pages.
    • It should return a single variable that will be passed as the argument to getQueryInputArguments()
  • manual: Boolean
    • Set this to true to disable automatic refetching when the query mounts or changes query keys.
    • To refetch the query, use the refetch method returned from the useQuery instance.
  • enabled: Boolean
    • Set this to false to disable automatic refetching when the query mounts or changes query keys.
    • To refetch the query, use the refetch method returned from the useQuery instance.
  • retry: Boolean | Int | Function(failureCount, error) => shouldRetry | Boolean
    • If false, failed queries will not retry by default.
    • If true, failed queries will retry infinitely.
    • If set to an Int, e.g. 3, failed queries will retry until the failed query count meets that number.
    • If set to a function (failureCount, error) => boolean failed queries will retry until the function returns false.
  • retryDelay: Function(retryAttempt: Int) => Int
    • This function receives a retryAttempt integer and returns the delay to apply before the next attempt in milliseconds.
    • A function like attempt => Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 30 * 1000) applies exponential backoff.
    • A function like attempt => attempt * 1000 applies linear backoff.
  • staleTime: Int | Infinity
    • The time in milliseconds that cache data remains fresh. After a successful cache update, that cache data will become stale after this duration.
    • If set to Infinity, query will never go stale
  • cacheTime: Int | Infinity
    • The time in milliseconds that unused/inactive cache data remains in memory. When a query's cache becomes unused or inactive, that cache data will be garbage collected after this duration.
    • If set to Infinity, will disable garbage collection
  • refetchInterval: false | Integer
    • Optional
    • If set to a number, all queries will continuously refetch at this frequency in milliseconds
  • refetchIntervalInBackground: Boolean
    • Optional
    • If set to true, queries that are set to continuously refetch with a refetchInterval will continue to refetch while their tab/window is in the background
  • refetchOnWindowFocus: Boolean
    • Optional
    • Set this to false to disable automatic refetching on window focus (useful, when refetchAllOnWindowFocus is set to true).
    • Set this to true to enable automatic refetching on window focus (useful, when refetchAllOnWindowFocus is set to false.
  • onSuccess: Function(data) => data
    • Optional
    • This function will fire any time the query successfully fetches new data.
  • onError: Function(err) => void
    • Optional
    • This function will fire if the query encounters an error and will be passed the error.
  • onSettled: Function(data, error) => data
    • Optional
    • This function will fire any time the query is either successfully fetched or errors and be passed either the data or error
  • initialData: any
    • Optional
    • If set, this value will be used as the initial data for the query cache (as long as the query hasn't been created or cached yet)
  • refetchOnMount: Boolean
    • Optional
    • Defaults to true
    • If set to false, will disable additional instances of a query to trigger background refetches
  • suspense: Boolean
    • Optional
    • Enabled by default. Set this to false to disable suspense mode.

Returns

[groupedQueryFunctionResults, queryExtras]

groupedQueryFunctionResults: Array<any>
  • Defaults to [].
  • The array will contain each "page" of data that has been requested
queryExtras: Object
  • isFetching: Boolean
    • Defaults to true so long as manual is set to false
    • Will be true if the query is currently fetching, including background fetching.
  • failureCount: Integer
    • The failure count for the query.
    • Incremented every time the query fails.
    • Reset to 0 when the query succeeds.
  • refetch() - Function({ force, throwOnError }) => void
    • A function to manually refetch the query if it is stale.
    • To bypass the stale check, you can pass the force: true option and refetch it regardless of it's freshness
    • If the query errors, the error will only be logged. If you want an error to be thrown, pass the throwOnError: true option
  • fetchMore() - Function(fetchMoreVariableOverride, { previous }) => Promise
    • This function allows you to fetch the next "page" of results.
    • fetchMoreVariableOverride allows you to optionally override the fetch more variable returned from your getCanFetchMore option to your query function to retrieve the next page of results.
    • previous option which will determine if the data you are fetching is should be prepended instead of appended to your infinite list. e.g. fetchMore(nextPageVars, { previous: true })
  • canFetchMore: Boolean
    • If using paginated mode, this will be true if there is more data to be fetched (known via the required getFetchMore option function).
  • mutate() - Function(newData, opts) => void
    • A function to manually update the cache for a query.
    • newData can be an object of new data or a function that receives the old data and returns the new data
    • This is often used to instantly update the cache after submitting a form
    • After updating the cache, this will automatically call refetch() to ensure the data is correct. Disable refetch by passing an options object {refetch: false} as the second argument.
    • See the Blitz mutation usage docs for example usage of mutate()
Idea for improving this page?Edit it on Github