From b2f7d88f107cbfb58d6c2d90b55c7459295c7db0 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 26 Aug 2026 16:44:21 +0900 Subject: [PATCH 01/30] docs(preact-query): wrap 'useIsFetching' example in a component --- .../preact/reference/functions/useIsFetching.md | 12 +++++++----- packages/preact-query/src/useIsFetching.ts | 10 ++++++---- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/docs/framework/preact/reference/functions/useIsFetching.md b/docs/framework/preact/reference/functions/useIsFetching.md index 75aea1a394..915c55fab0 100644 --- a/docs/framework/preact/reference/functions/useIsFetching.md +++ b/docs/framework/preact/reference/functions/useIsFetching.md @@ -7,7 +7,7 @@ title: useIsFetching function useIsFetching(filters?, queryClient?): number; ``` -Defined in: [preact-query/src/useIsFetching.ts:42](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useIsFetching.ts#L42) +Defined in: [preact-query/src/useIsFetching.ts:44](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useIsFetching.ts#L44) `useIsFetching` is an optional hook that returns the `number` of the queries that your application is loading or fetching in the background (useful for app-wide loading indicators). @@ -39,10 +39,12 @@ background. ```tsx import { useIsFetching } from '@tanstack/preact-query' -// How many queries are fetching? -const isFetching = useIsFetching() -// How many queries matching the posts prefix are fetching? -const isFetchingPosts = useIsFetching({ queryKey: ['posts'] }) +function PostsFetchingIndicator() { + // How many queries matching the posts prefix are fetching? + const isFetchingPosts = useIsFetching({ queryKey: ['posts'] }) + + return isFetchingPosts ? Refreshing posts... : null +} ``` A global loading indicator for any query fetching in the background, not just the ones on screen: diff --git a/packages/preact-query/src/useIsFetching.ts b/packages/preact-query/src/useIsFetching.ts index 9deac24f6c..16c00bbf95 100644 --- a/packages/preact-query/src/useIsFetching.ts +++ b/packages/preact-query/src/useIsFetching.ts @@ -19,10 +19,12 @@ import { useSyncExternalStore } from './utils' * ```tsx * import { useIsFetching } from '@tanstack/preact-query' * - * // How many queries are fetching? - * const isFetching = useIsFetching() - * // How many queries matching the posts prefix are fetching? - * const isFetchingPosts = useIsFetching({ queryKey: ['posts'] }) + * function PostsFetchingIndicator() { + * // How many queries matching the posts prefix are fetching? + * const isFetchingPosts = useIsFetching({ queryKey: ['posts'] }) + * + * return isFetchingPosts ? Refreshing posts... : null + * } * ``` * * @example From ce37641dce8a5191f0a0ca80ff4b9c83cdb6720c Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 26 Aug 2026 16:44:21 +0900 Subject: [PATCH 02/30] docs(preact-query): wrap 'useQueries' examples in components and add 'isError' handling --- .../preact/reference/functions/useQueries.md | 70 +++++++++++++------ packages/preact-query/src/useQueries.ts | 68 ++++++++++++------ 2 files changed, 95 insertions(+), 43 deletions(-) diff --git a/docs/framework/preact/reference/functions/useQueries.md b/docs/framework/preact/reference/functions/useQueries.md index 154077759f..668211e1d3 100644 --- a/docs/framework/preact/reference/functions/useQueries.md +++ b/docs/framework/preact/reference/functions/useQueries.md @@ -7,7 +7,7 @@ title: useQueries function useQueries(__namedParameters, queryClient?): TCombinedResult; ``` -Defined in: [preact-query/src/useQueries.ts:275](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useQueries.ts#L275) +Defined in: [preact-query/src/useQueries.ts:301](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useQueries.ts#L301) The `useQueries` hook can be used to fetch a variable number of queries. @@ -83,29 +83,55 @@ order as the input. When `combine` is provided, this is the value returned by `c ```tsx import { useQueries } from '@tanstack/preact-query' -const ids = [1, 2, 3] -const results = useQueries({ - queries: ids.map((id) => ({ - queryKey: ['post', id], - queryFn: () => fetchPost(id), - staleTime: Infinity, - })), -}) +function Posts({ ids }: { ids: Array }) { + const postQueries = useQueries({ + queries: ids.map((id) => ({ + queryKey: ['post', id], + queryFn: () => fetchPost(id), + staleTime: Infinity, + })), + }) + + return ( +
    + {postQueries.map((query, index) => { + if (query.isPending) return
  • Loading...
  • + if (query.isError) return
  • Error: {query.error.message}
  • + return
  • {query.data.title}
  • + })} +
+ ) +} ``` Combining results into a single value: ```tsx -const ids = [1, 2, 3] -const combinedQueries = useQueries({ - queries: ids.map((id) => ({ - queryKey: ['post', id], - queryFn: () => fetchPost(id), - })), - combine: (results) => { - return { - data: results.map((result) => result.data), - pending: results.some((result) => result.isPending), - } - }, -}) +import { useQueries } from '@tanstack/preact-query' + +function Posts({ ids }: { ids: Array }) { + const { data, isPending, isError } = useQueries({ + queries: ids.map((id) => ({ + queryKey: ['post', id], + queryFn: () => fetchPost(id), + })), + combine: (postQueries) => { + return { + data: postQueries.map((query) => query.data), + isPending: postQueries.some((query) => query.isPending), + isError: postQueries.some((query) => query.isError), + } + }, + }) + + if (isPending) return 'Loading...' + if (isError) return 'Error loading posts' + + return ( +
    + {data.map((post) => ( +
  • {post?.title}
  • + ))} +
+ ) +} ``` diff --git a/packages/preact-query/src/useQueries.ts b/packages/preact-query/src/useQueries.ts index 39a3d04316..52d4b45090 100644 --- a/packages/preact-query/src/useQueries.ts +++ b/packages/preact-query/src/useQueries.ts @@ -244,32 +244,58 @@ export type QueriesResults< * ```tsx * import { useQueries } from '@tanstack/preact-query' * - * const ids = [1, 2, 3] - * const results = useQueries({ - * queries: ids.map((id) => ({ - * queryKey: ['post', id], - * queryFn: () => fetchPost(id), - * staleTime: Infinity, - * })), - * }) + * function Posts({ ids }: { ids: Array }) { + * const postQueries = useQueries({ + * queries: ids.map((id) => ({ + * queryKey: ['post', id], + * queryFn: () => fetchPost(id), + * staleTime: Infinity, + * })), + * }) + * + * return ( + *
    + * {postQueries.map((query, index) => { + * if (query.isPending) return
  • Loading...
  • + * if (query.isError) return
  • Error: {query.error.message}
  • + * return
  • {query.data.title}
  • + * })} + *
+ * ) + * } * ``` * * @example * Combining results into a single value: * ```tsx - * const ids = [1, 2, 3] - * const combinedQueries = useQueries({ - * queries: ids.map((id) => ({ - * queryKey: ['post', id], - * queryFn: () => fetchPost(id), - * })), - * combine: (results) => { - * return { - * data: results.map((result) => result.data), - * pending: results.some((result) => result.isPending), - * } - * }, - * }) + * import { useQueries } from '@tanstack/preact-query' + * + * function Posts({ ids }: { ids: Array }) { + * const { data, isPending, isError } = useQueries({ + * queries: ids.map((id) => ({ + * queryKey: ['post', id], + * queryFn: () => fetchPost(id), + * })), + * combine: (postQueries) => { + * return { + * data: postQueries.map((query) => query.data), + * isPending: postQueries.some((query) => query.isPending), + * isError: postQueries.some((query) => query.isError), + * } + * }, + * }) + * + * if (isPending) return 'Loading...' + * if (isError) return 'Error loading posts' + * + * return ( + *
    + * {data.map((post) => ( + *
  • {post?.title}
  • + * ))} + *
+ * ) + * } * ``` */ export function useQueries< From 52e8c76842c1a1bab3f777f4665aeb435c27154e Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 26 Aug 2026 16:44:21 +0900 Subject: [PATCH 03/30] docs(preact-query): wrap 'useIsMutating' and 'useMutationState' examples in components --- .../reference/functions/useIsMutating.md | 12 ++-- .../reference/functions/useMutationState.md | 60 ++++++++++------ packages/preact-query/src/useMutationState.ts | 68 ++++++++++++------- 3 files changed, 90 insertions(+), 50 deletions(-) diff --git a/docs/framework/preact/reference/functions/useIsMutating.md b/docs/framework/preact/reference/functions/useIsMutating.md index 941496a00b..8b4954ffba 100644 --- a/docs/framework/preact/reference/functions/useIsMutating.md +++ b/docs/framework/preact/reference/functions/useIsMutating.md @@ -7,7 +7,7 @@ title: useIsMutating function useIsMutating(filters?, queryClient?): number; ``` -Defined in: [preact-query/src/useMutationState.ts:33](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useMutationState.ts#L33) +Defined in: [preact-query/src/useMutationState.ts:35](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useMutationState.ts#L35) `useIsMutating` is an optional hook that returns the `number` of mutations that your application is fetching (useful for app-wide loading indicators). @@ -38,8 +38,10 @@ Will be the `number` of the mutations that your application is currently fetchin ```tsx import { useIsMutating } from '@tanstack/preact-query' -// How many mutations are fetching? -const isMutating = useIsMutating() -// How many mutations matching the posts prefix are fetching? -const isMutatingPosts = useIsMutating({ mutationKey: ['posts'] }) +function PostsMutatingIndicator() { + // How many mutations matching the posts prefix are fetching? + const isMutatingPosts = useIsMutating({ mutationKey: ['posts'] }) + + return isMutatingPosts ? Saving posts... : null +} ``` diff --git a/docs/framework/preact/reference/functions/useMutationState.md b/docs/framework/preact/reference/functions/useMutationState.md index 6288bff6ef..89a6e82959 100644 --- a/docs/framework/preact/reference/functions/useMutationState.md +++ b/docs/framework/preact/reference/functions/useMutationState.md @@ -7,7 +7,7 @@ title: useMutationState function useMutationState(options, queryClient?): TResult[]; ``` -Defined in: [preact-query/src/useMutationState.ts:137](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useMutationState.ts#L137) +Defined in: [preact-query/src/useMutationState.ts:157](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useMutationState.ts#L157) `useMutationState` is a hook that gives you access to all mutations in the `MutationCache`. You can pass `filters` (MutationFilters) to narrow down your mutations, and `select` to transform the mutation @@ -51,10 +51,14 @@ Get all variables of all running mutations: ```tsx import { useMutationState } from '@tanstack/preact-query' -const variables = useMutationState({ - filters: { status: 'pending' }, - select: (mutation) => mutation.state.variables, -}) +function PendingPosts() { + const variables = useMutationState({ + filters: { status: 'pending' }, + select: (mutation) => mutation.state.variables, + }) + + return <>{variables.length} posts saving... +} ``` Get all data for specific mutations via the `mutationKey`: @@ -63,27 +67,41 @@ import { useMutation, useMutationState } from '@tanstack/preact-query' const mutationKey = ['posts'] -// Some mutation that we want to get the state for -const mutation = useMutation({ - mutationKey, - mutationFn: createPosts, -}) - -const data = useMutationState({ - // this mutation key needs to match the mutation key of the given mutation (see above) - filters: { mutationKey }, - select: (mutation) => mutation.state.data, -}) +function Posts() { + // Some mutation that we want to get the state for + const mutation = useMutation({ + mutationKey, + mutationFn: createPosts, + }) + + const data = useMutationState({ + // this mutation key needs to match the mutation key of the given mutation (see above) + filters: { mutationKey }, + select: (mutation) => mutation.state.data, + }) + + return ( + + ) +} ``` Access the latest mutation data via the `mutationKey`. Each invocation of `mutate` adds a new entry to the mutation cache for `gcTime` milliseconds — check the last item that `useMutationState` returns to get the latest invocation: ```tsx -const data = useMutationState({ - filters: { mutationKey: ['posts'] }, - select: (mutation) => mutation.state.data, -}) +import { useMutationState } from '@tanstack/preact-query' + +function LatestPost() { + const data = useMutationState({ + filters: { mutationKey: ['posts'] }, + select: (mutation) => mutation.state.data, + }) + + const latest = data[data.length - 1] -const latest = data[data.length - 1] + return <>{latest ? 'Saved' : 'Nothing saved yet'} +} ``` diff --git a/packages/preact-query/src/useMutationState.ts b/packages/preact-query/src/useMutationState.ts index beb5318217..a3f483651a 100644 --- a/packages/preact-query/src/useMutationState.ts +++ b/packages/preact-query/src/useMutationState.ts @@ -24,10 +24,12 @@ import { useSyncExternalStore } from './utils' * ```tsx * import { useIsMutating } from '@tanstack/preact-query' * - * // How many mutations are fetching? - * const isMutating = useIsMutating() - * // How many mutations matching the posts prefix are fetching? - * const isMutatingPosts = useIsMutating({ mutationKey: ['posts'] }) + * function PostsMutatingIndicator() { + * // How many mutations matching the posts prefix are fetching? + * const isMutatingPosts = useIsMutating({ mutationKey: ['posts'] }) + * + * return isMutatingPosts ? Saving posts... : null + * } * ``` */ export function useIsMutating( @@ -95,10 +97,14 @@ function getResult< * ```tsx * import { useMutationState } from '@tanstack/preact-query' * - * const variables = useMutationState({ - * filters: { status: 'pending' }, - * select: (mutation) => mutation.state.variables, - * }) + * function PendingPosts() { + * const variables = useMutationState({ + * filters: { status: 'pending' }, + * select: (mutation) => mutation.state.variables, + * }) + * + * return <>{variables.length} posts saving... + * } * ``` * * @example @@ -108,17 +114,25 @@ function getResult< * * const mutationKey = ['posts'] * - * // Some mutation that we want to get the state for - * const mutation = useMutation({ - * mutationKey, - * mutationFn: createPosts, - * }) - * - * const data = useMutationState({ - * // this mutation key needs to match the mutation key of the given mutation (see above) - * filters: { mutationKey }, - * select: (mutation) => mutation.state.data, - * }) + * function Posts() { + * // Some mutation that we want to get the state for + * const mutation = useMutation({ + * mutationKey, + * mutationFn: createPosts, + * }) + * + * const data = useMutationState({ + * // this mutation key needs to match the mutation key of the given mutation (see above) + * filters: { mutationKey }, + * select: (mutation) => mutation.state.data, + * }) + * + * return ( + * + * ) + * } * ``` * * @example @@ -126,12 +140,18 @@ function getResult< * mutation cache for `gcTime` milliseconds — check the last item that `useMutationState` returns to get the * latest invocation: * ```tsx - * const data = useMutationState({ - * filters: { mutationKey: ['posts'] }, - * select: (mutation) => mutation.state.data, - * }) + * import { useMutationState } from '@tanstack/preact-query' + * + * function LatestPost() { + * const data = useMutationState({ + * filters: { mutationKey: ['posts'] }, + * select: (mutation) => mutation.state.data, + * }) + * + * const latest = data[data.length - 1] * - * const latest = data[data.length - 1] + * return <>{latest ? 'Saved' : 'Nothing saved yet'} + * } * ``` */ export function useMutationState< From 0685b2e215bf4ab712fa46cb3c7156b536c37a87 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 26 Aug 2026 16:44:21 +0900 Subject: [PATCH 04/30] docs(preact-query): wrap 'queryOptions' examples in components --- .../reference/functions/queryOptions.md | 48 +++++++++++-------- packages/preact-query/src/queryOptions.ts | 44 ++++++++++------- 2 files changed, 54 insertions(+), 38 deletions(-) diff --git a/docs/framework/preact/reference/functions/queryOptions.md b/docs/framework/preact/reference/functions/queryOptions.md index 88e114030c..67ffd67b7e 100644 --- a/docs/framework/preact/reference/functions/queryOptions.md +++ b/docs/framework/preact/reference/functions/queryOptions.md @@ -75,7 +75,7 @@ function Posts() { function queryOptions(options): OmitKeyof, "queryFn"> & object & QueryKeyWithDataTag; ``` -Defined in: [preact-query/src/queryOptions.ts:201](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L201) +Defined in: [preact-query/src/queryOptions.ts:205](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L205) You can generally pass everything to `queryOptions` that you can also pass to `useQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.query`. `options.queryKey` is required and @@ -118,12 +118,17 @@ The same options object, typed so that `queryKey` carries the inferred data type ### Examples ```tsx -import { queryOptions } from '@tanstack/preact-query' +import { queryOptions, useQuery } from '@tanstack/preact-query' export const postsOptions = queryOptions({ queryKey: ['posts'], queryFn: fetchPosts, }) + +function Posts() { + const { data } = useQuery(postsOptions) + return <>{data?.map((post) =>

{post.title}

)} +} ``` A parameterized factory, reused across a hook and an imperative call with the same cache entry: @@ -147,20 +152,19 @@ queryClient.query(postOptions(id)).catch(noop) The same options object works with every API that accepts query options: ```tsx -import { - noop, - queryOptions, - useQuery, - useSuspenseQuery, -} from '@tanstack/preact-query' +import { noop, queryOptions, useQuery } from '@tanstack/preact-query' const todosOptions = queryOptions({ queryKey: ['todos'], queryFn: fetchTodos, }) -useQuery(todosOptions) -useSuspenseQuery(todosOptions) +function Todos() { + const { data } = useQuery(todosOptions) + return <>{data?.map((todo) =>

{todo.title}

)} +} + +// Elsewhere, e.g. to warm the cache before rendering ``: queryClient.query(todosOptions).catch(noop) queryClient.getQueryData(todosOptions.queryKey) // typed as Array | undefined ``` @@ -171,7 +175,7 @@ queryClient.getQueryData(todosOptions.queryKey) // typed as Array | undefi function queryOptions(options): UseQueryOptions & object & QueryKeyWithDataTag; ``` -Defined in: [preact-query/src/queryOptions.ts:271](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L271) +Defined in: [preact-query/src/queryOptions.ts:279](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L279) You can generally pass everything to `queryOptions` that you can also pass to `useQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.query`. `options.queryKey` is required and @@ -214,12 +218,17 @@ The same options object, typed so that `queryKey` carries the inferred data type ### Examples ```tsx -import { queryOptions } from '@tanstack/preact-query' +import { queryOptions, useQuery } from '@tanstack/preact-query' export const postsOptions = queryOptions({ queryKey: ['posts'], queryFn: fetchPosts, }) + +function Posts() { + const { data } = useQuery(postsOptions) + return <>{data?.map((post) =>

{post.title}

)} +} ``` A parameterized factory, reused across a hook and an imperative call with the same cache entry: @@ -243,20 +252,19 @@ queryClient.query(postOptions(id)).catch(noop) The same options object works with every API that accepts query options: ```tsx -import { - noop, - queryOptions, - useQuery, - useSuspenseQuery, -} from '@tanstack/preact-query' +import { noop, queryOptions, useQuery } from '@tanstack/preact-query' const todosOptions = queryOptions({ queryKey: ['todos'], queryFn: fetchTodos, }) -useQuery(todosOptions) -useSuspenseQuery(todosOptions) +function Todos() { + const { data } = useQuery(todosOptions) + return <>{data?.map((todo) =>

{todo.title}

)} +} + +// Elsewhere, e.g. to warm the cache before rendering ``: queryClient.query(todosOptions).catch(noop) queryClient.getQueryData(todosOptions.queryKey) // typed as Array | undefined ``` diff --git a/packages/preact-query/src/queryOptions.ts b/packages/preact-query/src/queryOptions.ts index 440306fce4..db8350dd53 100644 --- a/packages/preact-query/src/queryOptions.ts +++ b/packages/preact-query/src/queryOptions.ts @@ -149,12 +149,17 @@ export function queryOptions< * * @example * ```tsx - * import { queryOptions } from '@tanstack/preact-query' + * import { queryOptions, useQuery } from '@tanstack/preact-query' * * export const postsOptions = queryOptions({ * queryKey: ['posts'], * queryFn: fetchPosts, * }) + * + * function Posts() { + * const { data } = useQuery(postsOptions) + * return <>{data?.map((post) =>

{post.title}

)} + * } * ``` * * @example @@ -180,20 +185,19 @@ export function queryOptions< * @example * The same options object works with every API that accepts query options: * ```tsx - * import { - * noop, - * queryOptions, - * useQuery, - * useSuspenseQuery, - * } from '@tanstack/preact-query' + * import { noop, queryOptions, useQuery } from '@tanstack/preact-query' * * const todosOptions = queryOptions({ * queryKey: ['todos'], * queryFn: fetchTodos, * }) * - * useQuery(todosOptions) - * useSuspenseQuery(todosOptions) + * function Todos() { + * const { data } = useQuery(todosOptions) + * return <>{data?.map((todo) =>

{todo.title}

)} + * } + * + * // Elsewhere, e.g. to warm the cache before rendering ``: * queryClient.query(todosOptions).catch(noop) * queryClient.getQueryData(todosOptions.queryKey) // typed as Array | undefined * ``` @@ -219,12 +223,17 @@ export function queryOptions< * * @example * ```tsx - * import { queryOptions } from '@tanstack/preact-query' + * import { queryOptions, useQuery } from '@tanstack/preact-query' * * export const postsOptions = queryOptions({ * queryKey: ['posts'], * queryFn: fetchPosts, * }) + * + * function Posts() { + * const { data } = useQuery(postsOptions) + * return <>{data?.map((post) =>

{post.title}

)} + * } * ``` * * @example @@ -250,20 +259,19 @@ export function queryOptions< * @example * The same options object works with every API that accepts query options: * ```tsx - * import { - * noop, - * queryOptions, - * useQuery, - * useSuspenseQuery, - * } from '@tanstack/preact-query' + * import { noop, queryOptions, useQuery } from '@tanstack/preact-query' * * const todosOptions = queryOptions({ * queryKey: ['todos'], * queryFn: fetchTodos, * }) * - * useQuery(todosOptions) - * useSuspenseQuery(todosOptions) + * function Todos() { + * const { data } = useQuery(todosOptions) + * return <>{data?.map((todo) =>

{todo.title}

)} + * } + * + * // Elsewhere, e.g. to warm the cache before rendering ``: * queryClient.query(todosOptions).catch(noop) * queryClient.getQueryData(todosOptions.queryKey) // typed as Array | undefined * ``` From 28ca24c4a6b77937fe97ab4b97fcb4f643fdd47c Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 26 Aug 2026 16:44:21 +0900 Subject: [PATCH 05/30] docs(preact-query): wrap 'infiniteQueryOptions' example in a component --- .../functions/infiniteQueryOptions.md | 18 ++++++++++++++---- .../preact-query/src/infiniteQueryOptions.ts | 14 ++++++++++++-- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/docs/framework/preact/reference/functions/infiniteQueryOptions.md b/docs/framework/preact/reference/functions/infiniteQueryOptions.md index d28fe91935..d0bc2d79d0 100644 --- a/docs/framework/preact/reference/functions/infiniteQueryOptions.md +++ b/docs/framework/preact/reference/functions/infiniteQueryOptions.md @@ -80,7 +80,7 @@ function Projects() { function infiniteQueryOptions(options): OmitKeyof, "queryFn"> & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:233](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L233) +Defined in: [preact-query/src/infiniteQueryOptions.ts:238](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L238) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -123,7 +123,7 @@ The same options object, typed so that `queryKey` carries the inferred data type ### Examples ```tsx -import { infiniteQueryOptions } from '@tanstack/preact-query' +import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/preact-query' export const projectsOptions = infiniteQueryOptions({ queryKey: ['projects'], @@ -131,6 +131,11 @@ export const projectsOptions = infiniteQueryOptions({ initialPageParam: 0, getNextPageParam: (lastPage) => lastPage.nextId, }) + +function Projects() { + const { data } = useInfiniteQuery(projectsOptions) + return <>{data?.pages.map((page) => page.projects.map((p) =>

{p.name}

))} +} ``` A parameterized factory, reused across a hook and an imperative call with the same cache entry: @@ -173,7 +178,7 @@ queryClient.infiniteQuery(commentsOptions(postId)).catch(noop) function infiniteQueryOptions(options): UseInfiniteQueryOptions & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:309](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L309) +Defined in: [preact-query/src/infiniteQueryOptions.ts:319](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L319) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -216,7 +221,7 @@ The same options object, typed so that `queryKey` carries the inferred data type ### Examples ```tsx -import { infiniteQueryOptions } from '@tanstack/preact-query' +import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/preact-query' export const projectsOptions = infiniteQueryOptions({ queryKey: ['projects'], @@ -224,6 +229,11 @@ export const projectsOptions = infiniteQueryOptions({ initialPageParam: 0, getNextPageParam: (lastPage) => lastPage.nextId, }) + +function Projects() { + const { data } = useInfiniteQuery(projectsOptions) + return <>{data?.pages.map((page) => page.projects.map((p) =>

{p.name}

))} +} ``` A parameterized factory, reused across a hook and an imperative call with the same cache entry: diff --git a/packages/preact-query/src/infiniteQueryOptions.ts b/packages/preact-query/src/infiniteQueryOptions.ts index bece80eeb6..918fd58c23 100644 --- a/packages/preact-query/src/infiniteQueryOptions.ts +++ b/packages/preact-query/src/infiniteQueryOptions.ts @@ -186,7 +186,7 @@ export function infiniteQueryOptions< * * @example * ```tsx - * import { infiniteQueryOptions } from '@tanstack/preact-query' + * import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/preact-query' * * export const projectsOptions = infiniteQueryOptions({ * queryKey: ['projects'], @@ -194,6 +194,11 @@ export function infiniteQueryOptions< * initialPageParam: 0, * getNextPageParam: (lastPage) => lastPage.nextId, * }) + * + * function Projects() { + * const { data } = useInfiniteQuery(projectsOptions) + * return <>{data?.pages.map((page) => page.projects.map((p) =>

{p.name}

))} + * } * ``` * * @example @@ -262,7 +267,7 @@ export function infiniteQueryOptions< * * @example * ```tsx - * import { infiniteQueryOptions } from '@tanstack/preact-query' + * import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/preact-query' * * export const projectsOptions = infiniteQueryOptions({ * queryKey: ['projects'], @@ -270,6 +275,11 @@ export function infiniteQueryOptions< * initialPageParam: 0, * getNextPageParam: (lastPage) => lastPage.nextId, * }) + * + * function Projects() { + * const { data } = useInfiniteQuery(projectsOptions) + * return <>{data?.pages.map((page) => page.projects.map((p) =>

{p.name}

))} + * } * ``` * * @example From e553284ad2356c42f82e7adfa6296c0588bcdfdd Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 26 Aug 2026 16:58:31 +0900 Subject: [PATCH 06/30] fix(preact-query): correctly distinguish error state from loading in 'infiniteQueryOptions' example --- .../preact/reference/functions/infiniteQueryOptions.md | 10 ++++++---- packages/preact-query/src/infiniteQueryOptions.ts | 6 ++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/framework/preact/reference/functions/infiniteQueryOptions.md b/docs/framework/preact/reference/functions/infiniteQueryOptions.md index d0bc2d79d0..f828e90cad 100644 --- a/docs/framework/preact/reference/functions/infiniteQueryOptions.md +++ b/docs/framework/preact/reference/functions/infiniteQueryOptions.md @@ -80,7 +80,7 @@ function Projects() { function infiniteQueryOptions(options): OmitKeyof, "queryFn"> & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:238](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L238) +Defined in: [preact-query/src/infiniteQueryOptions.ts:239](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L239) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -156,7 +156,8 @@ export const commentsOptions = (postId: string) => function Comments({ postId }: { postId: string }) { const result = useInfiniteQuery(commentsOptions(postId)) - if (!result.isSuccess) return 'Loading...' + if (result.isPending) return 'Loading...' + if (result.isError) return Error: {result.error.message} return ( <> {result.data.pages.map((page) => page.comments.map((c) =>

{c.text}

))} @@ -178,7 +179,7 @@ queryClient.infiniteQuery(commentsOptions(postId)).catch(noop) function infiniteQueryOptions(options): UseInfiniteQueryOptions & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:319](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L319) +Defined in: [preact-query/src/infiniteQueryOptions.ts:321](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L321) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -254,7 +255,8 @@ export const commentsOptions = (postId: string) => function Comments({ postId }: { postId: string }) { const result = useInfiniteQuery(commentsOptions(postId)) - if (!result.isSuccess) return 'Loading...' + if (result.isPending) return 'Loading...' + if (result.isError) return Error: {result.error.message} return ( <> {result.data.pages.map((page) => page.comments.map((c) =>

{c.text}

))} diff --git a/packages/preact-query/src/infiniteQueryOptions.ts b/packages/preact-query/src/infiniteQueryOptions.ts index 918fd58c23..0035bc4a7f 100644 --- a/packages/preact-query/src/infiniteQueryOptions.ts +++ b/packages/preact-query/src/infiniteQueryOptions.ts @@ -220,7 +220,8 @@ export function infiniteQueryOptions< * * function Comments({ postId }: { postId: string }) { * const result = useInfiniteQuery(commentsOptions(postId)) - * if (!result.isSuccess) return 'Loading...' + * if (result.isPending) return 'Loading...' + * if (result.isError) return Error: {result.error.message} * return ( * <> * {result.data.pages.map((page) => page.comments.map((c) =>

{c.text}

))} @@ -301,7 +302,8 @@ export function infiniteQueryOptions< * * function Comments({ postId }: { postId: string }) { * const result = useInfiniteQuery(commentsOptions(postId)) - * if (!result.isSuccess) return 'Loading...' + * if (result.isPending) return 'Loading...' + * if (result.isError) return Error: {result.error.message} * return ( * <> * {result.data.pages.map((page) => page.comments.map((c) =>

{c.text}

))} From 700ce6fed7c8adac360a198bcffc62cf711d4318 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 26 Aug 2026 17:16:58 +0900 Subject: [PATCH 07/30] fix(preact-query): correct mutation terminology and filter by success status in 'useMutationState' examples --- docs/framework/preact/reference/functions/useIsMutating.md | 2 +- .../preact/reference/functions/useMutationState.md | 4 ++-- packages/preact-query/src/useMutationState.ts | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/framework/preact/reference/functions/useIsMutating.md b/docs/framework/preact/reference/functions/useIsMutating.md index 8b4954ffba..bfc97539bd 100644 --- a/docs/framework/preact/reference/functions/useIsMutating.md +++ b/docs/framework/preact/reference/functions/useIsMutating.md @@ -39,7 +39,7 @@ Will be the `number` of the mutations that your application is currently fetchin import { useIsMutating } from '@tanstack/preact-query' function PostsMutatingIndicator() { - // How many mutations matching the posts prefix are fetching? + // How many mutations matching the posts prefix are in progress? const isMutatingPosts = useIsMutating({ mutationKey: ['posts'] }) return isMutatingPosts ? Saving posts... : null diff --git a/docs/framework/preact/reference/functions/useMutationState.md b/docs/framework/preact/reference/functions/useMutationState.md index 89a6e82959..93c2cb93e7 100644 --- a/docs/framework/preact/reference/functions/useMutationState.md +++ b/docs/framework/preact/reference/functions/useMutationState.md @@ -76,7 +76,7 @@ function Posts() { const data = useMutationState({ // this mutation key needs to match the mutation key of the given mutation (see above) - filters: { mutationKey }, + filters: { mutationKey, status: 'success' }, select: (mutation) => mutation.state.data, }) @@ -96,7 +96,7 @@ import { useMutationState } from '@tanstack/preact-query' function LatestPost() { const data = useMutationState({ - filters: { mutationKey: ['posts'] }, + filters: { mutationKey: ['posts'], status: 'success' }, select: (mutation) => mutation.state.data, }) diff --git a/packages/preact-query/src/useMutationState.ts b/packages/preact-query/src/useMutationState.ts index a3f483651a..f6910d10a7 100644 --- a/packages/preact-query/src/useMutationState.ts +++ b/packages/preact-query/src/useMutationState.ts @@ -25,7 +25,7 @@ import { useSyncExternalStore } from './utils' * import { useIsMutating } from '@tanstack/preact-query' * * function PostsMutatingIndicator() { - * // How many mutations matching the posts prefix are fetching? + * // How many mutations matching the posts prefix are in progress? * const isMutatingPosts = useIsMutating({ mutationKey: ['posts'] }) * * return isMutatingPosts ? Saving posts... : null @@ -123,7 +123,7 @@ function getResult< * * const data = useMutationState({ * // this mutation key needs to match the mutation key of the given mutation (see above) - * filters: { mutationKey }, + * filters: { mutationKey, status: 'success' }, * select: (mutation) => mutation.state.data, * }) * @@ -144,7 +144,7 @@ function getResult< * * function LatestPost() { * const data = useMutationState({ - * filters: { mutationKey: ['posts'] }, + * filters: { mutationKey: ['posts'], status: 'success' }, * select: (mutation) => mutation.state.data, * }) * From 0c086bc07d5181fccf97f00d8f3c4dc28ccbd85b Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 26 Aug 2026 18:13:48 +0900 Subject: [PATCH 08/30] docs(preact-query): destructure useInfiniteQuery result in 'infiniteQueryOptions' example --- .../reference/functions/infiniteQueryOptions.md | 16 ++++++++-------- .../preact-query/src/infiniteQueryOptions.ts | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/framework/preact/reference/functions/infiniteQueryOptions.md b/docs/framework/preact/reference/functions/infiniteQueryOptions.md index f828e90cad..e98e1daee4 100644 --- a/docs/framework/preact/reference/functions/infiniteQueryOptions.md +++ b/docs/framework/preact/reference/functions/infiniteQueryOptions.md @@ -155,12 +155,12 @@ export const commentsOptions = (postId: string) => }) function Comments({ postId }: { postId: string }) { - const result = useInfiniteQuery(commentsOptions(postId)) - if (result.isPending) return 'Loading...' - if (result.isError) return Error: {result.error.message} + const { data, isPending, isError, error } = useInfiniteQuery(commentsOptions(postId)) + if (isPending) return 'Loading...' + if (isError) return Error: {error.message} return ( <> - {result.data.pages.map((page) => page.comments.map((c) =>

{c.text}

))} + {data.pages.map((page) => page.comments.map((c) =>

{c.text}

))} ) } @@ -254,12 +254,12 @@ export const commentsOptions = (postId: string) => }) function Comments({ postId }: { postId: string }) { - const result = useInfiniteQuery(commentsOptions(postId)) - if (result.isPending) return 'Loading...' - if (result.isError) return Error: {result.error.message} + const { data, isPending, isError, error } = useInfiniteQuery(commentsOptions(postId)) + if (isPending) return 'Loading...' + if (isError) return Error: {error.message} return ( <> - {result.data.pages.map((page) => page.comments.map((c) =>

{c.text}

))} + {data.pages.map((page) => page.comments.map((c) =>

{c.text}

))} ) } diff --git a/packages/preact-query/src/infiniteQueryOptions.ts b/packages/preact-query/src/infiniteQueryOptions.ts index 0035bc4a7f..52945406d6 100644 --- a/packages/preact-query/src/infiniteQueryOptions.ts +++ b/packages/preact-query/src/infiniteQueryOptions.ts @@ -219,12 +219,12 @@ export function infiniteQueryOptions< * }) * * function Comments({ postId }: { postId: string }) { - * const result = useInfiniteQuery(commentsOptions(postId)) - * if (result.isPending) return 'Loading...' - * if (result.isError) return Error: {result.error.message} + * const { data, isPending, isError, error } = useInfiniteQuery(commentsOptions(postId)) + * if (isPending) return 'Loading...' + * if (isError) return Error: {error.message} * return ( * <> - * {result.data.pages.map((page) => page.comments.map((c) =>

{c.text}

))} + * {data.pages.map((page) => page.comments.map((c) =>

{c.text}

))} * * ) * } @@ -301,12 +301,12 @@ export function infiniteQueryOptions< * }) * * function Comments({ postId }: { postId: string }) { - * const result = useInfiniteQuery(commentsOptions(postId)) - * if (result.isPending) return 'Loading...' - * if (result.isError) return Error: {result.error.message} + * const { data, isPending, isError, error } = useInfiniteQuery(commentsOptions(postId)) + * if (isPending) return 'Loading...' + * if (isError) return Error: {error.message} * return ( * <> - * {result.data.pages.map((page) => page.comments.map((c) =>

{c.text}

))} + * {data.pages.map((page) => page.comments.map((c) =>

{c.text}

))} * * ) * } From 4ad73e09fbce2afdb58a2ce3788abdbaa60c97ad Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 26 Aug 2026 18:18:38 +0900 Subject: [PATCH 09/30] docs(preact-query): rename 'variables' to 'pendingVariables' in 'useMutationState' example --- docs/framework/preact/reference/functions/useMutationState.md | 4 ++-- packages/preact-query/src/useMutationState.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/framework/preact/reference/functions/useMutationState.md b/docs/framework/preact/reference/functions/useMutationState.md index 93c2cb93e7..432103c51e 100644 --- a/docs/framework/preact/reference/functions/useMutationState.md +++ b/docs/framework/preact/reference/functions/useMutationState.md @@ -52,12 +52,12 @@ Get all variables of all running mutations: import { useMutationState } from '@tanstack/preact-query' function PendingPosts() { - const variables = useMutationState({ + const pendingVariables = useMutationState({ filters: { status: 'pending' }, select: (mutation) => mutation.state.variables, }) - return <>{variables.length} posts saving... + return <>{pendingVariables.length} posts saving... } ``` diff --git a/packages/preact-query/src/useMutationState.ts b/packages/preact-query/src/useMutationState.ts index f6910d10a7..cc17a71ba9 100644 --- a/packages/preact-query/src/useMutationState.ts +++ b/packages/preact-query/src/useMutationState.ts @@ -98,12 +98,12 @@ function getResult< * import { useMutationState } from '@tanstack/preact-query' * * function PendingPosts() { - * const variables = useMutationState({ + * const pendingVariables = useMutationState({ * filters: { status: 'pending' }, * select: (mutation) => mutation.state.variables, * }) * - * return <>{variables.length} posts saving... + * return <>{pendingVariables.length} posts saving... * } * ``` * From 5d70bbe1c6d53ea73c1868d51077c394fead87b4 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 26 Aug 2026 18:20:20 +0900 Subject: [PATCH 10/30] docs(preact-query): rename 'data' to 'savedPosts' in 'useMutationState' examples --- .../preact/reference/functions/useMutationState.md | 8 ++++---- packages/preact-query/src/useMutationState.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/framework/preact/reference/functions/useMutationState.md b/docs/framework/preact/reference/functions/useMutationState.md index 432103c51e..e389a25451 100644 --- a/docs/framework/preact/reference/functions/useMutationState.md +++ b/docs/framework/preact/reference/functions/useMutationState.md @@ -74,7 +74,7 @@ function Posts() { mutationFn: createPosts, }) - const data = useMutationState({ + const savedPosts = useMutationState({ // this mutation key needs to match the mutation key of the given mutation (see above) filters: { mutationKey, status: 'success' }, select: (mutation) => mutation.state.data, @@ -82,7 +82,7 @@ function Posts() { return ( ) } @@ -95,12 +95,12 @@ latest invocation: import { useMutationState } from '@tanstack/preact-query' function LatestPost() { - const data = useMutationState({ + const savedPosts = useMutationState({ filters: { mutationKey: ['posts'], status: 'success' }, select: (mutation) => mutation.state.data, }) - const latest = data[data.length - 1] + const latest = savedPosts[savedPosts.length - 1] return <>{latest ? 'Saved' : 'Nothing saved yet'} } diff --git a/packages/preact-query/src/useMutationState.ts b/packages/preact-query/src/useMutationState.ts index cc17a71ba9..58acc2414d 100644 --- a/packages/preact-query/src/useMutationState.ts +++ b/packages/preact-query/src/useMutationState.ts @@ -121,7 +121,7 @@ function getResult< * mutationFn: createPosts, * }) * - * const data = useMutationState({ + * const savedPosts = useMutationState({ * // this mutation key needs to match the mutation key of the given mutation (see above) * filters: { mutationKey, status: 'success' }, * select: (mutation) => mutation.state.data, @@ -129,7 +129,7 @@ function getResult< * * return ( * * ) * } @@ -143,12 +143,12 @@ function getResult< * import { useMutationState } from '@tanstack/preact-query' * * function LatestPost() { - * const data = useMutationState({ + * const savedPosts = useMutationState({ * filters: { mutationKey: ['posts'], status: 'success' }, * select: (mutation) => mutation.state.data, * }) * - * const latest = data[data.length - 1] + * const latest = savedPosts[savedPosts.length - 1] * * return <>{latest ? 'Saved' : 'Nothing saved yet'} * } From d64829fb2e7aee2bfa903eed2be8b6d36282e9a6 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 26 Aug 2026 18:23:16 +0900 Subject: [PATCH 11/30] docs(preact-query): rename 'results'/'result' to 'addResults'/'addResult' in 'useMutation' Promise.allSettled example --- docs/framework/preact/reference/functions/useMutation.md | 8 ++++---- packages/preact-query/src/useMutation.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/framework/preact/reference/functions/useMutation.md b/docs/framework/preact/reference/functions/useMutation.md index f01293841b..a5c6fe1939 100644 --- a/docs/framework/preact/reference/functions/useMutation.md +++ b/docs/framework/preact/reference/functions/useMutation.md @@ -193,13 +193,13 @@ function AddTodos() { }) async function handleAddAll(todos: Array) { - const results = await Promise.allSettled( + const addResults = await Promise.allSettled( todos.map((todo) => addMutation.mutateAsync(todo)), ) - results.forEach((result, index) => { - if (result.status === 'rejected') { - console.error(`Failed to add "${todos[index]}":`, result.reason) + addResults.forEach((addResult, index) => { + if (addResult.status === 'rejected') { + console.error(`Failed to add "${todos[index]}":`, addResult.reason) } }) } diff --git a/packages/preact-query/src/useMutation.ts b/packages/preact-query/src/useMutation.ts index 68a3759d93..bd4baf0326 100644 --- a/packages/preact-query/src/useMutation.ts +++ b/packages/preact-query/src/useMutation.ts @@ -168,13 +168,13 @@ import { useSyncExternalStore } from './utils' * }) * * async function handleAddAll(todos: Array) { - * const results = await Promise.allSettled( + * const addResults = await Promise.allSettled( * todos.map((todo) => addMutation.mutateAsync(todo)), * ) * - * results.forEach((result, index) => { - * if (result.status === 'rejected') { - * console.error(`Failed to add "${todos[index]}":`, result.reason) + * addResults.forEach((addResult, index) => { + * if (addResult.status === 'rejected') { + * console.error(`Failed to add "${todos[index]}":`, addResult.reason) * } * }) * } From 64b10ce7ed477a8d6b18ba3e4b03a957e24eda44 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 26 Aug 2026 18:23:16 +0900 Subject: [PATCH 12/30] docs(preact-query): rename 'latest' to 'latestSavedPost' in 'useMutationState' example --- docs/framework/preact/reference/functions/useMutationState.md | 4 ++-- packages/preact-query/src/useMutationState.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/framework/preact/reference/functions/useMutationState.md b/docs/framework/preact/reference/functions/useMutationState.md index e389a25451..37bee7a2f6 100644 --- a/docs/framework/preact/reference/functions/useMutationState.md +++ b/docs/framework/preact/reference/functions/useMutationState.md @@ -100,8 +100,8 @@ function LatestPost() { select: (mutation) => mutation.state.data, }) - const latest = savedPosts[savedPosts.length - 1] + const latestSavedPost = savedPosts[savedPosts.length - 1] - return <>{latest ? 'Saved' : 'Nothing saved yet'} + return <>{latestSavedPost ? 'Saved' : 'Nothing saved yet'} } ``` diff --git a/packages/preact-query/src/useMutationState.ts b/packages/preact-query/src/useMutationState.ts index 58acc2414d..58e154a394 100644 --- a/packages/preact-query/src/useMutationState.ts +++ b/packages/preact-query/src/useMutationState.ts @@ -148,9 +148,9 @@ function getResult< * select: (mutation) => mutation.state.data, * }) * - * const latest = savedPosts[savedPosts.length - 1] + * const latestSavedPost = savedPosts[savedPosts.length - 1] * - * return <>{latest ? 'Saved' : 'Nothing saved yet'} + * return <>{latestSavedPost ? 'Saved' : 'Nothing saved yet'} * } * ``` */ From ec6828a351ea337124f2f65d88f4f20c22c2d251 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 26 Aug 2026 21:25:55 +0900 Subject: [PATCH 13/30] docs(preact-query): render fetched pages and handle loading/error states in 'useInfiniteQuery' examples --- .../reference/functions/useInfiniteQuery.md | 104 ++++++++++++------ packages/preact-query/src/useInfiniteQuery.ts | 100 +++++++++++------ 2 files changed, 134 insertions(+), 70 deletions(-) diff --git a/docs/framework/preact/reference/functions/useInfiniteQuery.md b/docs/framework/preact/reference/functions/useInfiniteQuery.md index 3eaadf977b..e777d17e06 100644 --- a/docs/framework/preact/reference/functions/useInfiniteQuery.md +++ b/docs/framework/preact/reference/functions/useInfiniteQuery.md @@ -95,7 +95,7 @@ function Projects() { function useInfiniteQuery(options, queryClient?): UseInfiniteQueryResult; ``` -Defined in: [preact-query/src/useInfiniteQuery.ts:115](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L115) +Defined in: [preact-query/src/useInfiniteQuery.ts:131](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L131) The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of `queryFn`, `initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`. @@ -161,25 +161,41 @@ actions, or add conditions like `hasNextPage && !isFetching`. import { useInfiniteQuery } from '@tanstack/preact-query' function Projects() { - const { data, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } = - useInfiniteQuery({ - queryKey: ['projects'], - queryFn: ({ pageParam }) => fetchProjects(pageParam), - initialPageParam: 0, - getNextPageParam: (lastPage) => lastPage.nextId, - }) + const { + data, + isPending, + isError, + error, + fetchNextPage, + hasNextPage, + isFetching, + isFetchingNextPage, + } = useInfiniteQuery({ + queryKey: ['projects'], + queryFn: ({ pageParam }) => fetchProjects(pageParam), + initialPageParam: 0, + getNextPageParam: (lastPage) => lastPage.nextId, + }) + + if (isPending) return 'Loading...' + if (isError) return Error: {error.message} return ( - + <> + {data.pages.map((page) => + page.projects.map((project) =>

{project.name}

), + )} + + ) } ``` @@ -190,7 +206,7 @@ function Projects() { function useInfiniteQuery(options, queryClient?): UseInfiniteQueryResult; ``` -Defined in: [preact-query/src/useInfiniteQuery.ts:175](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L175) +Defined in: [preact-query/src/useInfiniteQuery.ts:207](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L207) The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of `queryFn`, `initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`. @@ -256,25 +272,41 @@ actions, or add conditions like `hasNextPage && !isFetching`. import { useInfiniteQuery } from '@tanstack/preact-query' function Projects() { - const { data, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } = - useInfiniteQuery({ - queryKey: ['projects'], - queryFn: ({ pageParam }) => fetchProjects(pageParam), - initialPageParam: 0, - getNextPageParam: (lastPage) => lastPage.nextId, - }) + const { + data, + isPending, + isError, + error, + fetchNextPage, + hasNextPage, + isFetching, + isFetchingNextPage, + } = useInfiniteQuery({ + queryKey: ['projects'], + queryFn: ({ pageParam }) => fetchProjects(pageParam), + initialPageParam: 0, + getNextPageParam: (lastPage) => lastPage.nextId, + }) + + if (isPending) return 'Loading...' + if (isError) return Error: {error.message} return ( - + <> + {data.pages.map((page) => + page.projects.map((project) =>

{project.name}

), + )} + + ) } ``` diff --git a/packages/preact-query/src/useInfiniteQuery.ts b/packages/preact-query/src/useInfiniteQuery.ts index a525029ca7..49276bcd72 100644 --- a/packages/preact-query/src/useInfiniteQuery.ts +++ b/packages/preact-query/src/useInfiniteQuery.ts @@ -89,25 +89,41 @@ export function useInfiniteQuery< * import { useInfiniteQuery } from '@tanstack/preact-query' * * function Projects() { - * const { data, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } = - * useInfiniteQuery({ - * queryKey: ['projects'], - * queryFn: ({ pageParam }) => fetchProjects(pageParam), - * initialPageParam: 0, - * getNextPageParam: (lastPage) => lastPage.nextId, - * }) + * const { + * data, + * isPending, + * isError, + * error, + * fetchNextPage, + * hasNextPage, + * isFetching, + * isFetchingNextPage, + * } = useInfiniteQuery({ + * queryKey: ['projects'], + * queryFn: ({ pageParam }) => fetchProjects(pageParam), + * initialPageParam: 0, + * getNextPageParam: (lastPage) => lastPage.nextId, + * }) + * + * if (isPending) return 'Loading...' + * if (isError) return Error: {error.message} * * return ( - * + * <> + * {data.pages.map((page) => + * page.projects.map((project) =>

{project.name}

), + * )} + * + * * ) * } * ``` @@ -149,25 +165,41 @@ export function useInfiniteQuery< * import { useInfiniteQuery } from '@tanstack/preact-query' * * function Projects() { - * const { data, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } = - * useInfiniteQuery({ - * queryKey: ['projects'], - * queryFn: ({ pageParam }) => fetchProjects(pageParam), - * initialPageParam: 0, - * getNextPageParam: (lastPage) => lastPage.nextId, - * }) + * const { + * data, + * isPending, + * isError, + * error, + * fetchNextPage, + * hasNextPage, + * isFetching, + * isFetchingNextPage, + * } = useInfiniteQuery({ + * queryKey: ['projects'], + * queryFn: ({ pageParam }) => fetchProjects(pageParam), + * initialPageParam: 0, + * getNextPageParam: (lastPage) => lastPage.nextId, + * }) + * + * if (isPending) return 'Loading...' + * if (isError) return Error: {error.message} * * return ( - * + * <> + * {data.pages.map((page) => + * page.projects.map((project) =>

{project.name}

), + * )} + * + * * ) * } * ``` From 1c8408016f3cd3bba65a1dfb3767cdb5e6c35eb2 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Sat, 29 Aug 2026 10:58:20 +0900 Subject: [PATCH 14/30] docs(preact-query): render infinite query lists as '
    '/'
  • ' instead of flat '

    ' tags --- .../functions/infiniteQueryOptions.md | 36 ++++++++++++------- .../reference/functions/useInfiniteQuery.md | 20 ++++++----- .../preact-query/src/infiniteQueryOptions.ts | 30 +++++++++++----- packages/preact-query/src/useInfiniteQuery.ts | 16 +++++---- 4 files changed, 67 insertions(+), 35 deletions(-) diff --git a/docs/framework/preact/reference/functions/infiniteQueryOptions.md b/docs/framework/preact/reference/functions/infiniteQueryOptions.md index e98e1daee4..1b3f9e42f7 100644 --- a/docs/framework/preact/reference/functions/infiniteQueryOptions.md +++ b/docs/framework/preact/reference/functions/infiniteQueryOptions.md @@ -9,7 +9,7 @@ title: infiniteQueryOptions function infiniteQueryOptions(options): UseInfiniteQueryOptions & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:157](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L157) +Defined in: [preact-query/src/infiniteQueryOptions.ts:161](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L161) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -70,7 +70,11 @@ export const projectsOptions = infiniteQueryOptions({ function Projects() { const { data } = useInfiniteQuery(projectsOptions) - return <>{data.pages.map((page) => page.projects.map((p) =>

    {p.name}

    ))} + return ( +
      + {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} +
    + ) } ``` @@ -80,7 +84,7 @@ function Projects() { function infiniteQueryOptions(options): OmitKeyof, "queryFn"> & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:239](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L239) +Defined in: [preact-query/src/infiniteQueryOptions.ts:247](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L247) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -134,7 +138,11 @@ export const projectsOptions = infiniteQueryOptions({ function Projects() { const { data } = useInfiniteQuery(projectsOptions) - return <>{data?.pages.map((page) => page.projects.map((p) =>

    {p.name}

    ))} + return ( +
      + {data?.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} +
    + ) } ``` @@ -159,9 +167,9 @@ function Comments({ postId }: { postId: string }) { if (isPending) return 'Loading...' if (isError) return Error: {error.message} return ( - <> - {data.pages.map((page) => page.comments.map((c) =>

    {c.text}

    ))} - +
      + {data.pages.map((page) => page.comments.map((c) =>
    • {c.text}
    • ))} +
    ) } @@ -179,7 +187,7 @@ queryClient.infiniteQuery(commentsOptions(postId)).catch(noop) function infiniteQueryOptions(options): UseInfiniteQueryOptions & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:321](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L321) +Defined in: [preact-query/src/infiniteQueryOptions.ts:333](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L333) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -233,7 +241,11 @@ export const projectsOptions = infiniteQueryOptions({ function Projects() { const { data } = useInfiniteQuery(projectsOptions) - return <>{data?.pages.map((page) => page.projects.map((p) =>

    {p.name}

    ))} + return ( +
      + {data?.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} +
    + ) } ``` @@ -258,9 +270,9 @@ function Comments({ postId }: { postId: string }) { if (isPending) return 'Loading...' if (isError) return Error: {error.message} return ( - <> - {data.pages.map((page) => page.comments.map((c) =>

    {c.text}

    ))} - +
      + {data.pages.map((page) => page.comments.map((c) =>
    • {c.text}
    • ))} +
    ) } diff --git a/docs/framework/preact/reference/functions/useInfiniteQuery.md b/docs/framework/preact/reference/functions/useInfiniteQuery.md index e777d17e06..3cc3febe0a 100644 --- a/docs/framework/preact/reference/functions/useInfiniteQuery.md +++ b/docs/framework/preact/reference/functions/useInfiniteQuery.md @@ -95,7 +95,7 @@ function Projects() { function useInfiniteQuery(options, queryClient?): UseInfiniteQueryResult; ``` -Defined in: [preact-query/src/useInfiniteQuery.ts:131](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L131) +Defined in: [preact-query/src/useInfiniteQuery.ts:133](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L133) The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of `queryFn`, `initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`. @@ -182,9 +182,11 @@ function Projects() { return ( <> - {data.pages.map((page) => - page.projects.map((project) =>

    {project.name}

    ), - )} +
      + {data.pages.map((page) => + page.projects.map((project) =>
    • {project.name}
    • ), + )} +
    + ) : null} ) } ``` +See [useInfiniteQuery](useInfiniteQuery.md) for an example that fetches the next page automatically as the +user scrolls, instead of on a button click. + ## Call Signature ```ts function infiniteQueryOptions(options): OmitKeyof, "queryFn"> & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:259](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L259) +Defined in: [preact-query/src/infiniteQueryOptions.ts:275](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L275) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -143,19 +150,28 @@ export const projectsOptions = infiniteQueryOptions({ }) function Projects() { - const { data, isPending, isError, error } = useInfiniteQuery(projectsOptions) + const { data, isPending, isError, error, fetchNextPage, hasNextPage } = + useInfiniteQuery(projectsOptions) if (isPending) return 'Loading...' if (isError) return Error: {error.message} return ( -
      - {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} -
    +
    +
      + {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} +
    + {hasNextPage ? ( + + ) : null} +
    ) } ``` +See [useInfiniteQuery](useInfiniteQuery.md) for an example that fetches the next page automatically as the +user scrolls, instead of on a button click. + A parameterized factory, reused across a hook and an imperative call with the same cache entry: ```tsx import { @@ -199,7 +215,7 @@ queryClient.infiniteQuery(commentsOptions(postId)).catch(noop) function infiniteQueryOptions(options): UseInfiniteQueryOptions & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:387](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L387) +Defined in: [preact-query/src/infiniteQueryOptions.ts:412](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L412) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -252,19 +268,28 @@ export const projectsOptions = infiniteQueryOptions({ }) function Projects() { - const { data, isPending, isError, error } = useInfiniteQuery(projectsOptions) + const { data, isPending, isError, error, fetchNextPage, hasNextPage } = + useInfiniteQuery(projectsOptions) if (isPending) return 'Loading...' if (isError) return Error: {error.message} return ( -
      - {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} -
    +
    +
      + {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} +
    + {hasNextPage ? ( + + ) : null} +
    ) } ``` +See [useInfiniteQuery](useInfiniteQuery.md) for an example that fetches the next page automatically as the +user scrolls, instead of on a button click. + A parameterized factory, reused across a hook and an imperative call with the same cache entry: ```tsx import { diff --git a/docs/framework/preact/reference/functions/useInfiniteQuery.md b/docs/framework/preact/reference/functions/useInfiniteQuery.md index 831cd6fe6a..691fb990db 100644 --- a/docs/framework/preact/reference/functions/useInfiniteQuery.md +++ b/docs/framework/preact/reference/functions/useInfiniteQuery.md @@ -166,25 +166,34 @@ actions, or add conditions like `hasNextPage && !isFetching`. ### Example +Fetching the next page automatically as the user scrolls, using an `IntersectionObserver` on a +sentinel element after the list: ```tsx import { useInfiniteQuery } from '@tanstack/preact-query' +import { useEffect, useRef } from 'preact/hooks' function Projects() { - const { - data, - isPending, - isError, - error, - fetchNextPage, - hasNextPage, - isFetching, - isFetchingNextPage, - } = useInfiniteQuery({ - queryKey: ['projects'], - queryFn: ({ pageParam }) => fetchProjects(pageParam), - initialPageParam: 0, - getNextPageParam: (lastPage) => lastPage.nextId, - }) + const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetchingNextPage } = + useInfiniteQuery({ + queryKey: ['projects'], + queryFn: ({ pageParam }) => fetchProjects(pageParam), + initialPageParam: 0, + getNextPageParam: (lastPage) => lastPage.nextId, + }) + + const sentinelRef = useRef(null) + + useEffect(() => { + const sentinel = sentinelRef.current + if (sentinel == null || !hasNextPage) return + + const observer = new IntersectionObserver(([entry]) => { + if (entry.isIntersecting) fetchNextPage() + }) + observer.observe(sentinel) + + return () => observer.disconnect() + }, [hasNextPage, fetchNextPage]) if (isPending) return 'Loading...' if (isError) return Error: {error.message} @@ -196,16 +205,7 @@ function Projects() { page.projects.map((project) =>
  • {project.name}
  • ), )}
- +
{isFetchingNextPage ? 'Loading more...' : null}
) } @@ -279,25 +279,34 @@ actions, or add conditions like `hasNextPage && !isFetching`. ### Examples +Fetching the next page automatically as the user scrolls, using an `IntersectionObserver` on a +sentinel element after the list: ```tsx import { useInfiniteQuery } from '@tanstack/preact-query' +import { useEffect, useRef } from 'preact/hooks' function Projects() { - const { - data, - isPending, - isError, - error, - fetchNextPage, - hasNextPage, - isFetching, - isFetchingNextPage, - } = useInfiniteQuery({ - queryKey: ['projects'], - queryFn: ({ pageParam }) => fetchProjects(pageParam), - initialPageParam: 0, - getNextPageParam: (lastPage) => lastPage.nextId, - }) + const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetchingNextPage } = + useInfiniteQuery({ + queryKey: ['projects'], + queryFn: ({ pageParam }) => fetchProjects(pageParam), + initialPageParam: 0, + getNextPageParam: (lastPage) => lastPage.nextId, + }) + + const sentinelRef = useRef(null) + + useEffect(() => { + const sentinel = sentinelRef.current + if (sentinel == null || !hasNextPage) return + + const observer = new IntersectionObserver(([entry]) => { + if (entry.isIntersecting) fetchNextPage() + }) + observer.observe(sentinel) + + return () => observer.disconnect() + }, [hasNextPage, fetchNextPage]) if (isPending) return 'Loading...' if (isError) return Error: {error.message} @@ -309,16 +318,7 @@ function Projects() { page.projects.map((project) =>
  • {project.name}
  • ), )} - +
    {isFetchingNextPage ? 'Loading more...' : null}
    ) } diff --git a/packages/preact-query/src/infiniteQueryOptions.ts b/packages/preact-query/src/infiniteQueryOptions.ts index 5e1cd58835..7147ee2884 100644 --- a/packages/preact-query/src/infiniteQueryOptions.ts +++ b/packages/preact-query/src/infiniteQueryOptions.ts @@ -151,7 +151,8 @@ export type DefinedInitialDataInfiniteOptions< * function Projects() { * // `data` is never `undefined`, thanks to `initialData` — even if a refetch fails, so the * // list stays visible alongside the error. - * const { data, isError, error } = useInfiniteQuery(projectsOptions) + * const { data, isError, error, fetchNextPage, hasNextPage } = + * useInfiniteQuery(projectsOptions) * * return ( *
    @@ -159,10 +160,16 @@ export type DefinedInitialDataInfiniteOptions< *
      * {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} *
    + * {hasNextPage ? ( + * + * ) : null} *
    * ) * } * ``` + * + * See {@link useInfiniteQuery} for an example that fetches the next page automatically as the + * user scrolls, instead of on a button click. */ export function infiniteQueryOptions< TQueryFnData, @@ -206,19 +213,28 @@ export function infiniteQueryOptions< * }) * * function Projects() { - * const { data, isPending, isError, error } = useInfiniteQuery(projectsOptions) + * const { data, isPending, isError, error, fetchNextPage, hasNextPage } = + * useInfiniteQuery(projectsOptions) * * if (isPending) return 'Loading...' * if (isError) return Error: {error.message} * * return ( - *
      - * {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} - *
    + *
    + *
      + * {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} + *
    + * {hasNextPage ? ( + * + * ) : null} + *
    * ) * } * ``` * + * See {@link useInfiniteQuery} for an example that fetches the next page automatically as the + * user scrolls, instead of on a button click. + * * @example * A parameterized factory, reused across a hook and an imperative call with the same cache entry: * ```tsx @@ -298,19 +314,28 @@ export function infiniteQueryOptions< * }) * * function Projects() { - * const { data, isPending, isError, error } = useInfiniteQuery(projectsOptions) + * const { data, isPending, isError, error, fetchNextPage, hasNextPage } = + * useInfiniteQuery(projectsOptions) * * if (isPending) return 'Loading...' * if (isError) return Error: {error.message} * * return ( - *
      - * {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} - *
    + *
    + *
      + * {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} + *
    + * {hasNextPage ? ( + * + * ) : null} + *
    * ) * } * ``` * + * See {@link useInfiniteQuery} for an example that fetches the next page automatically as the + * user scrolls, instead of on a button click. + * * @example * A parameterized factory, reused across a hook and an imperative call with the same cache entry: * ```tsx diff --git a/packages/preact-query/src/useInfiniteQuery.ts b/packages/preact-query/src/useInfiniteQuery.ts index 39b639e111..fbc6afb81b 100644 --- a/packages/preact-query/src/useInfiniteQuery.ts +++ b/packages/preact-query/src/useInfiniteQuery.ts @@ -94,25 +94,34 @@ export function useInfiniteQuery< * `isFetchingPreviousPage`. * * @example + * Fetching the next page automatically as the user scrolls, using an `IntersectionObserver` on a + * sentinel element after the list: * ```tsx * import { useInfiniteQuery } from '@tanstack/preact-query' + * import { useEffect, useRef } from 'preact/hooks' * * function Projects() { - * const { - * data, - * isPending, - * isError, - * error, - * fetchNextPage, - * hasNextPage, - * isFetching, - * isFetchingNextPage, - * } = useInfiniteQuery({ - * queryKey: ['projects'], - * queryFn: ({ pageParam }) => fetchProjects(pageParam), - * initialPageParam: 0, - * getNextPageParam: (lastPage) => lastPage.nextId, - * }) + * const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetchingNextPage } = + * useInfiniteQuery({ + * queryKey: ['projects'], + * queryFn: ({ pageParam }) => fetchProjects(pageParam), + * initialPageParam: 0, + * getNextPageParam: (lastPage) => lastPage.nextId, + * }) + * + * const sentinelRef = useRef(null) + * + * useEffect(() => { + * const sentinel = sentinelRef.current + * if (sentinel == null || !hasNextPage) return + * + * const observer = new IntersectionObserver(([entry]) => { + * if (entry.isIntersecting) fetchNextPage() + * }) + * observer.observe(sentinel) + * + * return () => observer.disconnect() + * }, [hasNextPage, fetchNextPage]) * * if (isPending) return 'Loading...' * if (isError) return Error: {error.message} @@ -124,16 +133,7 @@ export function useInfiniteQuery< * page.projects.map((project) =>
  • {project.name}
  • ), * )} * - * + *
    {isFetchingNextPage ? 'Loading more...' : null}
    * * ) * } @@ -172,25 +172,34 @@ export function useInfiniteQuery< * `isFetchingPreviousPage`. * * @example + * Fetching the next page automatically as the user scrolls, using an `IntersectionObserver` on a + * sentinel element after the list: * ```tsx * import { useInfiniteQuery } from '@tanstack/preact-query' + * import { useEffect, useRef } from 'preact/hooks' * * function Projects() { - * const { - * data, - * isPending, - * isError, - * error, - * fetchNextPage, - * hasNextPage, - * isFetching, - * isFetchingNextPage, - * } = useInfiniteQuery({ - * queryKey: ['projects'], - * queryFn: ({ pageParam }) => fetchProjects(pageParam), - * initialPageParam: 0, - * getNextPageParam: (lastPage) => lastPage.nextId, - * }) + * const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetchingNextPage } = + * useInfiniteQuery({ + * queryKey: ['projects'], + * queryFn: ({ pageParam }) => fetchProjects(pageParam), + * initialPageParam: 0, + * getNextPageParam: (lastPage) => lastPage.nextId, + * }) + * + * const sentinelRef = useRef(null) + * + * useEffect(() => { + * const sentinel = sentinelRef.current + * if (sentinel == null || !hasNextPage) return + * + * const observer = new IntersectionObserver(([entry]) => { + * if (entry.isIntersecting) fetchNextPage() + * }) + * observer.observe(sentinel) + * + * return () => observer.disconnect() + * }, [hasNextPage, fetchNextPage]) * * if (isPending) return 'Loading...' * if (isError) return Error: {error.message} @@ -202,16 +211,7 @@ export function useInfiniteQuery< * page.projects.map((project) =>
  • {project.name}
  • ), * )} * - * + *
    {isFetchingNextPage ? 'Loading more...' : null}
    * * ) * } From 9509231ae0106d82e8391d0b5aeb2773d22f9acf Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Sun, 30 Aug 2026 11:59:36 +0900 Subject: [PATCH 24/30] docs(preact-query): guard scroll-triggered 'fetchNextPage' with 'isFetching', move cross-reference out of '@example' --- .../functions/infiniteQueryOptions.md | 30 ++++++---- .../reference/functions/useInfiniteQuery.md | 60 ++++++++++++------- .../preact-query/src/infiniteQueryOptions.ts | 15 ++--- packages/preact-query/src/useInfiniteQuery.ts | 56 ++++++++++------- 4 files changed, 98 insertions(+), 63 deletions(-) diff --git a/docs/framework/preact/reference/functions/infiniteQueryOptions.md b/docs/framework/preact/reference/functions/infiniteQueryOptions.md index 7afcb478ff..a003d6144b 100644 --- a/docs/framework/preact/reference/functions/infiniteQueryOptions.md +++ b/docs/framework/preact/reference/functions/infiniteQueryOptions.md @@ -9,7 +9,7 @@ title: infiniteQueryOptions function infiniteQueryOptions(options): UseInfiniteQueryOptions & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:174](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L174) +Defined in: [preact-query/src/infiniteQueryOptions.ts:173](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L173) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -55,6 +55,11 @@ The same options object, typed so that `queryKey` carries the inferred data type [useInfiniteQuery](useInfiniteQuery.md) to run an infinite query with these options. +### Remarks + +The example below fetches the next page from a button click. See [useInfiniteQuery](useInfiniteQuery.md) for a +version that fetches automatically as the user scrolls. + ### Example ```tsx @@ -88,16 +93,13 @@ function Projects() { } ``` -See [useInfiniteQuery](useInfiniteQuery.md) for an example that fetches the next page automatically as the -user scrolls, instead of on a button click. - ## Call Signature ```ts function infiniteQueryOptions(options): OmitKeyof, "queryFn"> & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:275](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L275) +Defined in: [preact-query/src/infiniteQueryOptions.ts:273](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L273) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -137,6 +139,11 @@ The [UnusedSkipTokenInfiniteOptions](../type-aliases/UnusedSkipTokenInfiniteOpti The same options object, typed so that `queryKey` carries the inferred data type. +### Remarks + +The first example below fetches the next page from a button click. See [useInfiniteQuery](useInfiniteQuery.md) +for a version that fetches automatically as the user scrolls. + ### Examples ```tsx @@ -169,9 +176,6 @@ function Projects() { } ``` -See [useInfiniteQuery](useInfiniteQuery.md) for an example that fetches the next page automatically as the -user scrolls, instead of on a button click. - A parameterized factory, reused across a hook and an imperative call with the same cache entry: ```tsx import { @@ -215,7 +219,7 @@ queryClient.infiniteQuery(commentsOptions(postId)).catch(noop) function infiniteQueryOptions(options): UseInfiniteQueryOptions & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:412](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L412) +Defined in: [preact-query/src/infiniteQueryOptions.ts:409](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L409) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -255,6 +259,11 @@ The [UndefinedInitialDataInfiniteOptions](../type-aliases/UndefinedInitialDataIn The same options object, typed so that `queryKey` carries the inferred data type. +### Remarks + +The first example below fetches the next page from a button click. See [useInfiniteQuery](useInfiniteQuery.md) +for a version that fetches automatically as the user scrolls. + ### Examples ```tsx @@ -287,9 +296,6 @@ function Projects() { } ``` -See [useInfiniteQuery](useInfiniteQuery.md) for an example that fetches the next page automatically as the -user scrolls, instead of on a button click. - A parameterized factory, reused across a hook and an imperative call with the same cache entry: ```tsx import { diff --git a/docs/framework/preact/reference/functions/useInfiniteQuery.md b/docs/framework/preact/reference/functions/useInfiniteQuery.md index 691fb990db..f7dcb324ae 100644 --- a/docs/framework/preact/reference/functions/useInfiniteQuery.md +++ b/docs/framework/preact/reference/functions/useInfiniteQuery.md @@ -104,7 +104,7 @@ function Projects() { function useInfiniteQuery(options, queryClient?): UseInfiniteQueryResult; ``` -Defined in: [preact-query/src/useInfiniteQuery.ts:142](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L142) +Defined in: [preact-query/src/useInfiniteQuery.ts:150](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L150) The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of `queryFn`, `initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`. @@ -173,27 +173,35 @@ import { useInfiniteQuery } from '@tanstack/preact-query' import { useEffect, useRef } from 'preact/hooks' function Projects() { - const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetchingNextPage } = - useInfiniteQuery({ - queryKey: ['projects'], - queryFn: ({ pageParam }) => fetchProjects(pageParam), - initialPageParam: 0, - getNextPageParam: (lastPage) => lastPage.nextId, - }) + const { + data, + isPending, + isError, + error, + fetchNextPage, + hasNextPage, + isFetching, + isFetchingNextPage, + } = useInfiniteQuery({ + queryKey: ['projects'], + queryFn: ({ pageParam }) => fetchProjects(pageParam), + initialPageParam: 0, + getNextPageParam: (lastPage) => lastPage.nextId, + }) const sentinelRef = useRef(null) useEffect(() => { const sentinel = sentinelRef.current - if (sentinel == null || !hasNextPage) return + if (sentinel == null || !hasNextPage || isFetching) return const observer = new IntersectionObserver(([entry]) => { - if (entry.isIntersecting) fetchNextPage() + if (entry?.isIntersecting) fetchNextPage() }) observer.observe(sentinel) return () => observer.disconnect() - }, [hasNextPage, fetchNextPage]) + }, [hasNextPage, isFetching, fetchNextPage]) if (isPending) return 'Loading...' if (isError) return Error: {error.message} @@ -217,7 +225,7 @@ function Projects() { function useInfiniteQuery(options, queryClient?): UseInfiniteQueryResult; ``` -Defined in: [preact-query/src/useInfiniteQuery.ts:294](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L294) +Defined in: [preact-query/src/useInfiniteQuery.ts:310](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L310) The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of `queryFn`, `initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`. @@ -286,27 +294,35 @@ import { useInfiniteQuery } from '@tanstack/preact-query' import { useEffect, useRef } from 'preact/hooks' function Projects() { - const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetchingNextPage } = - useInfiniteQuery({ - queryKey: ['projects'], - queryFn: ({ pageParam }) => fetchProjects(pageParam), - initialPageParam: 0, - getNextPageParam: (lastPage) => lastPage.nextId, - }) + const { + data, + isPending, + isError, + error, + fetchNextPage, + hasNextPage, + isFetching, + isFetchingNextPage, + } = useInfiniteQuery({ + queryKey: ['projects'], + queryFn: ({ pageParam }) => fetchProjects(pageParam), + initialPageParam: 0, + getNextPageParam: (lastPage) => lastPage.nextId, + }) const sentinelRef = useRef(null) useEffect(() => { const sentinel = sentinelRef.current - if (sentinel == null || !hasNextPage) return + if (sentinel == null || !hasNextPage || isFetching) return const observer = new IntersectionObserver(([entry]) => { - if (entry.isIntersecting) fetchNextPage() + if (entry?.isIntersecting) fetchNextPage() }) observer.observe(sentinel) return () => observer.disconnect() - }, [hasNextPage, fetchNextPage]) + }, [hasNextPage, isFetching, fetchNextPage]) if (isPending) return 'Loading...' if (isError) return Error: {error.message} diff --git a/packages/preact-query/src/infiniteQueryOptions.ts b/packages/preact-query/src/infiniteQueryOptions.ts index 7147ee2884..984ce62564 100644 --- a/packages/preact-query/src/infiniteQueryOptions.ts +++ b/packages/preact-query/src/infiniteQueryOptions.ts @@ -135,6 +135,8 @@ export type DefinedInitialDataInfiniteOptions< * @see {@link useInfiniteQuery} to run an infinite query with these options. * @param options - The {@link DefinedInitialDataInfiniteOptions} to use — everything you can pass to `useInfiniteQuery`, with `initialData` set. * @returns The same options object, typed so that `queryKey` carries the inferred data type. + * @remarks The example below fetches the next page from a button click. See {@link useInfiniteQuery} for a + * version that fetches automatically as the user scrolls. * * @example * ```tsx @@ -167,9 +169,6 @@ export type DefinedInitialDataInfiniteOptions< * ) * } * ``` - * - * See {@link useInfiniteQuery} for an example that fetches the next page automatically as the - * user scrolls, instead of on a button click. */ export function infiniteQueryOptions< TQueryFnData, @@ -200,6 +199,8 @@ export function infiniteQueryOptions< * `options.queryKey` is required and is the query key to generate options for. * * @returns The same options object, typed so that `queryKey` carries the inferred data type. + * @remarks The first example below fetches the next page from a button click. See {@link useInfiniteQuery} + * for a version that fetches automatically as the user scrolls. * * @example * ```tsx @@ -232,9 +233,6 @@ export function infiniteQueryOptions< * } * ``` * - * See {@link useInfiniteQuery} for an example that fetches the next page automatically as the - * user scrolls, instead of on a button click. - * * @example * A parameterized factory, reused across a hook and an imperative call with the same cache entry: * ```tsx @@ -301,6 +299,8 @@ export function infiniteQueryOptions< * `options.queryKey` is required and is the query key to generate options for. * * @returns The same options object, typed so that `queryKey` carries the inferred data type. + * @remarks The first example below fetches the next page from a button click. See {@link useInfiniteQuery} + * for a version that fetches automatically as the user scrolls. * * @example * ```tsx @@ -333,9 +333,6 @@ export function infiniteQueryOptions< * } * ``` * - * See {@link useInfiniteQuery} for an example that fetches the next page automatically as the - * user scrolls, instead of on a button click. - * * @example * A parameterized factory, reused across a hook and an imperative call with the same cache entry: * ```tsx diff --git a/packages/preact-query/src/useInfiniteQuery.ts b/packages/preact-query/src/useInfiniteQuery.ts index fbc6afb81b..1be82049ba 100644 --- a/packages/preact-query/src/useInfiniteQuery.ts +++ b/packages/preact-query/src/useInfiniteQuery.ts @@ -101,27 +101,35 @@ export function useInfiniteQuery< * import { useEffect, useRef } from 'preact/hooks' * * function Projects() { - * const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetchingNextPage } = - * useInfiniteQuery({ - * queryKey: ['projects'], - * queryFn: ({ pageParam }) => fetchProjects(pageParam), - * initialPageParam: 0, - * getNextPageParam: (lastPage) => lastPage.nextId, - * }) + * const { + * data, + * isPending, + * isError, + * error, + * fetchNextPage, + * hasNextPage, + * isFetching, + * isFetchingNextPage, + * } = useInfiniteQuery({ + * queryKey: ['projects'], + * queryFn: ({ pageParam }) => fetchProjects(pageParam), + * initialPageParam: 0, + * getNextPageParam: (lastPage) => lastPage.nextId, + * }) * * const sentinelRef = useRef(null) * * useEffect(() => { * const sentinel = sentinelRef.current - * if (sentinel == null || !hasNextPage) return + * if (sentinel == null || !hasNextPage || isFetching) return * * const observer = new IntersectionObserver(([entry]) => { - * if (entry.isIntersecting) fetchNextPage() + * if (entry?.isIntersecting) fetchNextPage() * }) * observer.observe(sentinel) * * return () => observer.disconnect() - * }, [hasNextPage, fetchNextPage]) + * }, [hasNextPage, isFetching, fetchNextPage]) * * if (isPending) return 'Loading...' * if (isError) return Error: {error.message} @@ -179,27 +187,35 @@ export function useInfiniteQuery< * import { useEffect, useRef } from 'preact/hooks' * * function Projects() { - * const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetchingNextPage } = - * useInfiniteQuery({ - * queryKey: ['projects'], - * queryFn: ({ pageParam }) => fetchProjects(pageParam), - * initialPageParam: 0, - * getNextPageParam: (lastPage) => lastPage.nextId, - * }) + * const { + * data, + * isPending, + * isError, + * error, + * fetchNextPage, + * hasNextPage, + * isFetching, + * isFetchingNextPage, + * } = useInfiniteQuery({ + * queryKey: ['projects'], + * queryFn: ({ pageParam }) => fetchProjects(pageParam), + * initialPageParam: 0, + * getNextPageParam: (lastPage) => lastPage.nextId, + * }) * * const sentinelRef = useRef(null) * * useEffect(() => { * const sentinel = sentinelRef.current - * if (sentinel == null || !hasNextPage) return + * if (sentinel == null || !hasNextPage || isFetching) return * * const observer = new IntersectionObserver(([entry]) => { - * if (entry.isIntersecting) fetchNextPage() + * if (entry?.isIntersecting) fetchNextPage() * }) * observer.observe(sentinel) * * return () => observer.disconnect() - * }, [hasNextPage, fetchNextPage]) + * }, [hasNextPage, isFetching, fetchNextPage]) * * if (isPending) return 'Loading...' * if (isError) return Error: {error.message} From 0c2834e270085a2c0f5fd31af9ab19a477d96c2b Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Sun, 30 Aug 2026 12:08:31 +0900 Subject: [PATCH 25/30] docs(preact-query): move duplicated usage examples from 'queryOptions'/'infiniteQueryOptions' into their hooks --- .../functions/infiniteQueryOptions.md | 123 ++---------------- .../reference/functions/queryOptions.md | 61 +++------ .../reference/functions/useInfiniteQuery.md | 82 +++++++++++- .../preact-query/src/infiniteQueryOptions.ts | 116 +---------------- packages/preact-query/src/queryOptions.ts | 52 +------- packages/preact-query/src/useInfiniteQuery.ts | 78 +++++++++++ 6 files changed, 198 insertions(+), 314 deletions(-) diff --git a/docs/framework/preact/reference/functions/infiniteQueryOptions.md b/docs/framework/preact/reference/functions/infiniteQueryOptions.md index a003d6144b..c7c714edea 100644 --- a/docs/framework/preact/reference/functions/infiniteQueryOptions.md +++ b/docs/framework/preact/reference/functions/infiniteQueryOptions.md @@ -9,7 +9,7 @@ title: infiniteQueryOptions function infiniteQueryOptions(options): UseInfiniteQueryOptions & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:173](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L173) +Defined in: [preact-query/src/infiniteQueryOptions.ts:169](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L169) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -57,8 +57,8 @@ The same options object, typed so that `queryKey` carries the inferred data type ### Remarks -The example below fetches the next page from a button click. See [useInfiniteQuery](useInfiniteQuery.md) for a -version that fetches automatically as the user scrolls. +See [useInfiniteQuery](useInfiniteQuery.md) for examples that fetch further pages, from a button click or +automatically as the user scrolls. ### Example @@ -76,8 +76,7 @@ export const projectsOptions = infiniteQueryOptions({ function Projects() { // `data` is never `undefined`, thanks to `initialData` — even if a refetch fails, so the // list stays visible alongside the error. - const { data, isError, error, fetchNextPage, hasNextPage } = - useInfiniteQuery(projectsOptions) + const { data, isError, error } = useInfiniteQuery(projectsOptions) return (
    @@ -85,9 +84,6 @@ function Projects() {
      {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))}
    - {hasNextPage ? ( - - ) : null}
    ) } @@ -99,7 +95,7 @@ function Projects() { function infiniteQueryOptions(options): OmitKeyof, "queryFn"> & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:273](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L273) +Defined in: [preact-query/src/infiniteQueryOptions.ts:238](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L238) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -141,40 +137,10 @@ The same options object, typed so that `queryKey` carries the inferred data type ### Remarks -The first example below fetches the next page from a button click. See [useInfiniteQuery](useInfiniteQuery.md) -for a version that fetches automatically as the user scrolls. +See [useInfiniteQuery](useInfiniteQuery.md) for examples that fetch further pages, from a button click or +automatically as the user scrolls. -### Examples - -```tsx -import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/preact-query' - -export const projectsOptions = infiniteQueryOptions({ - queryKey: ['projects'], - queryFn: ({ pageParam }) => fetchProjects(pageParam), - initialPageParam: 0, - getNextPageParam: (lastPage) => lastPage.nextId, -}) - -function Projects() { - const { data, isPending, isError, error, fetchNextPage, hasNextPage } = - useInfiniteQuery(projectsOptions) - - if (isPending) return 'Loading...' - if (isError) return Error: {error.message} - - return ( -
    -
      - {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} -
    - {hasNextPage ? ( - - ) : null} -
    - ) -} -``` +### Example A parameterized factory, reused across a hook and an imperative call with the same cache entry: ```tsx @@ -219,7 +185,7 @@ queryClient.infiniteQuery(commentsOptions(postId)).catch(noop) function infiniteQueryOptions(options): UseInfiniteQueryOptions & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:409](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L409) +Defined in: [preact-query/src/infiniteQueryOptions.ts:307](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L307) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -261,40 +227,10 @@ The same options object, typed so that `queryKey` carries the inferred data type ### Remarks -The first example below fetches the next page from a button click. See [useInfiniteQuery](useInfiniteQuery.md) -for a version that fetches automatically as the user scrolls. - -### Examples - -```tsx -import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/preact-query' - -export const projectsOptions = infiniteQueryOptions({ - queryKey: ['projects'], - queryFn: ({ pageParam }) => fetchProjects(pageParam), - initialPageParam: 0, - getNextPageParam: (lastPage) => lastPage.nextId, -}) - -function Projects() { - const { data, isPending, isError, error, fetchNextPage, hasNextPage } = - useInfiniteQuery(projectsOptions) - - if (isPending) return 'Loading...' - if (isError) return Error: {error.message} +See [useInfiniteQuery](useInfiniteQuery.md) for examples that fetch further pages (from a button click or +automatically as the user scrolls) and that use `skipToken` to disable the query until `postId` is set. - return ( -
    -
      - {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} -
    - {hasNextPage ? ( - - ) : null} -
    - ) -} -``` +### Example A parameterized factory, reused across a hook and an imperative call with the same cache entry: ```tsx @@ -329,41 +265,6 @@ const postId = '1' queryClient.infiniteQuery(commentsOptions(postId)).catch(noop) ``` -A factory that disables the query, type safe, until `postId` is set: -```tsx -import { - infiniteQueryOptions, - skipToken, - useInfiniteQuery, -} from '@tanstack/preact-query' - -export const commentsOptions = (postId: string | undefined) => - infiniteQueryOptions({ - queryKey: ['post', postId, 'comments'], - queryFn: - postId != null - ? ({ pageParam }) => fetchComments(postId, pageParam) - : skipToken, - initialPageParam: 0, - getNextPageParam: (lastPage) => lastPage.nextId, - }) - -function Comments({ postId }: { postId: string | undefined }) { - // Use `isLoading`, not `isPending`, so the loading state doesn't show while the query is disabled. - const { data, isLoading, isError, error } = useInfiniteQuery(commentsOptions(postId)) - - if (postId == null) return 'Select a post' - if (isLoading) return 'Loading...' - if (isError) return Error: {error.message} - - return ( -
      - {data?.pages.map((page) => page.comments.map((c) =>
    • {c.text}
    • ))} -
    - ) -} -``` - ### See [useInfiniteQuery](useInfiniteQuery.md) to run an infinite query with these options. diff --git a/docs/framework/preact/reference/functions/queryOptions.md b/docs/framework/preact/reference/functions/queryOptions.md index 3ca9efb150..672ca16cca 100644 --- a/docs/framework/preact/reference/functions/queryOptions.md +++ b/docs/framework/preact/reference/functions/queryOptions.md @@ -9,7 +9,7 @@ title: queryOptions function queryOptions(options): Omit, "queryFn"> & object & QueryKeyWithDataTag; ``` -Defined in: [preact-query/src/queryOptions.ts:140](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L140) +Defined in: [preact-query/src/queryOptions.ts:142](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L142) You can generally pass everything to `queryOptions` that you can also pass to `useQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.query`. `options.queryKey` is required and @@ -51,6 +51,11 @@ The same options object, typed so that `queryKey` carries the inferred data type [useQuery](useQuery.md) to run a query with these options. +### Remarks + +See [useQuery](useQuery.md) for more usage patterns — this factory works the same regardless of which +overload you use. + ### Example ```tsx @@ -84,7 +89,7 @@ function Posts() { function queryOptions(options): OmitKeyof, "queryFn"> & object & QueryKeyWithDataTag; ``` -Defined in: [preact-query/src/queryOptions.ts:234](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L234) +Defined in: [preact-query/src/queryOptions.ts:215](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L215) You can generally pass everything to `queryOptions` that you can also pass to `useQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.query`. `options.queryKey` is required and @@ -124,29 +129,12 @@ The same options object, typed so that `queryKey` carries the inferred data type [useQuery](useQuery.md) to run a query with these options. -### Examples +### Remarks -```tsx -import { queryOptions, useQuery } from '@tanstack/preact-query' +See [useQuery](useQuery.md) for more usage patterns — this factory works the same regardless of which +overload you use. -export const postsOptions = queryOptions({ - queryKey: ['posts'], - queryFn: fetchPosts, -}) - -function Posts() { - const { data, isPending, isError, error } = useQuery(postsOptions) - - if (isPending) return 'Loading...' - if (isError) return Error: {error.message} - - return ( -
      - {data.map((post) =>
    • {post.title}
    • )} -
    - ) -} -``` +### Examples A parameterized factory, reused across a hook and an imperative call with the same cache entry: ```tsx @@ -204,7 +192,7 @@ queryClient.getQueryData(todosOptions.queryKey) // typed as Array | undefi function queryOptions(options): UseQueryOptions & object & QueryKeyWithDataTag; ``` -Defined in: [preact-query/src/queryOptions.ts:350](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L350) +Defined in: [preact-query/src/queryOptions.ts:310](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L310) You can generally pass everything to `queryOptions` that you can also pass to `useQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.query`. `options.queryKey` is required and @@ -244,29 +232,12 @@ The same options object, typed so that `queryKey` carries the inferred data type [useQuery](useQuery.md) to run a query with these options. -### Examples - -```tsx -import { queryOptions, useQuery } from '@tanstack/preact-query' +### Remarks -export const postsOptions = queryOptions({ - queryKey: ['posts'], - queryFn: fetchPosts, -}) - -function Posts() { - const { data, isPending, isError, error } = useQuery(postsOptions) +See [useQuery](useQuery.md) for more usage patterns — this factory works the same regardless of which +overload you use. This is the only overload that accepts `queryFn: skipToken`, shown below. - if (isPending) return 'Loading...' - if (isError) return Error: {error.message} - - return ( -
      - {data.map((post) =>
    • {post.title}
    • )} -
    - ) -} -``` +### Examples A parameterized factory, reused across a hook and an imperative call with the same cache entry: ```tsx diff --git a/docs/framework/preact/reference/functions/useInfiniteQuery.md b/docs/framework/preact/reference/functions/useInfiniteQuery.md index f7dcb324ae..2075ddfc47 100644 --- a/docs/framework/preact/reference/functions/useInfiniteQuery.md +++ b/docs/framework/preact/reference/functions/useInfiniteQuery.md @@ -104,7 +104,7 @@ function Projects() { function useInfiniteQuery(options, queryClient?): UseInfiniteQueryResult; ``` -Defined in: [preact-query/src/useInfiniteQuery.ts:150](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L150) +Defined in: [preact-query/src/useInfiniteQuery.ts:189](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L189) The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of `queryFn`, `initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`. @@ -164,7 +164,45 @@ actions, or add conditions like `hasNextPage && !isFetching`. [infiniteQueryOptions](infiniteQueryOptions.md) to share these options between `useInfiniteQuery` and imperative APIs like `queryClient.infiniteQuery`. -### Example +### Examples + +Fetching the next page from a "Load More" button click: +```tsx +import { useInfiniteQuery } from '@tanstack/preact-query' + +function Projects() { + const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } = + useInfiniteQuery({ + queryKey: ['projects'], + queryFn: ({ pageParam }) => fetchProjects(pageParam), + initialPageParam: 0, + getNextPageParam: (lastPage) => lastPage.nextId, + }) + + if (isPending) return 'Loading...' + if (isError) return Error: {error.message} + + return ( + <> +
      + {data.pages.map((page) => + page.projects.map((project) =>
    • {project.name}
    • ), + )} +
    + + + ) +} +``` Fetching the next page automatically as the user scrolls, using an `IntersectionObserver` on a sentinel element after the list: @@ -225,7 +263,7 @@ function Projects() { function useInfiniteQuery(options, queryClient?): UseInfiniteQueryResult; ``` -Defined in: [preact-query/src/useInfiniteQuery.ts:310](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L310) +Defined in: [preact-query/src/useInfiniteQuery.ts:388](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L388) The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of `queryFn`, `initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`. @@ -287,6 +325,44 @@ actions, or add conditions like `hasNextPage && !isFetching`. ### Examples +Fetching the next page from a "Load More" button click: +```tsx +import { useInfiniteQuery } from '@tanstack/preact-query' + +function Projects() { + const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } = + useInfiniteQuery({ + queryKey: ['projects'], + queryFn: ({ pageParam }) => fetchProjects(pageParam), + initialPageParam: 0, + getNextPageParam: (lastPage) => lastPage.nextId, + }) + + if (isPending) return 'Loading...' + if (isError) return Error: {error.message} + + return ( + <> +
      + {data.pages.map((page) => + page.projects.map((project) =>
    • {project.name}
    • ), + )} +
    + + + ) +} +``` + Fetching the next page automatically as the user scrolls, using an `IntersectionObserver` on a sentinel element after the list: ```tsx diff --git a/packages/preact-query/src/infiniteQueryOptions.ts b/packages/preact-query/src/infiniteQueryOptions.ts index 984ce62564..3a61ecfe7a 100644 --- a/packages/preact-query/src/infiniteQueryOptions.ts +++ b/packages/preact-query/src/infiniteQueryOptions.ts @@ -135,8 +135,8 @@ export type DefinedInitialDataInfiniteOptions< * @see {@link useInfiniteQuery} to run an infinite query with these options. * @param options - The {@link DefinedInitialDataInfiniteOptions} to use — everything you can pass to `useInfiniteQuery`, with `initialData` set. * @returns The same options object, typed so that `queryKey` carries the inferred data type. - * @remarks The example below fetches the next page from a button click. See {@link useInfiniteQuery} for a - * version that fetches automatically as the user scrolls. + * @remarks See {@link useInfiniteQuery} for examples that fetch further pages, from a button click or + * automatically as the user scrolls. * * @example * ```tsx @@ -153,8 +153,7 @@ export type DefinedInitialDataInfiniteOptions< * function Projects() { * // `data` is never `undefined`, thanks to `initialData` — even if a refetch fails, so the * // list stays visible alongside the error. - * const { data, isError, error, fetchNextPage, hasNextPage } = - * useInfiniteQuery(projectsOptions) + * const { data, isError, error } = useInfiniteQuery(projectsOptions) * * return ( *
    @@ -162,9 +161,6 @@ export type DefinedInitialDataInfiniteOptions< *
      * {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} *
    - * {hasNextPage ? ( - * - * ) : null} *
    * ) * } @@ -199,39 +195,8 @@ export function infiniteQueryOptions< * `options.queryKey` is required and is the query key to generate options for. * * @returns The same options object, typed so that `queryKey` carries the inferred data type. - * @remarks The first example below fetches the next page from a button click. See {@link useInfiniteQuery} - * for a version that fetches automatically as the user scrolls. - * - * @example - * ```tsx - * import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/preact-query' - * - * export const projectsOptions = infiniteQueryOptions({ - * queryKey: ['projects'], - * queryFn: ({ pageParam }) => fetchProjects(pageParam), - * initialPageParam: 0, - * getNextPageParam: (lastPage) => lastPage.nextId, - * }) - * - * function Projects() { - * const { data, isPending, isError, error, fetchNextPage, hasNextPage } = - * useInfiniteQuery(projectsOptions) - * - * if (isPending) return 'Loading...' - * if (isError) return Error: {error.message} - * - * return ( - *
    - *
      - * {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} - *
    - * {hasNextPage ? ( - * - * ) : null} - *
    - * ) - * } - * ``` + * @remarks See {@link useInfiniteQuery} for examples that fetch further pages, from a button click or + * automatically as the user scrolls. * * @example * A parameterized factory, reused across a hook and an imperative call with the same cache entry: @@ -299,39 +264,8 @@ export function infiniteQueryOptions< * `options.queryKey` is required and is the query key to generate options for. * * @returns The same options object, typed so that `queryKey` carries the inferred data type. - * @remarks The first example below fetches the next page from a button click. See {@link useInfiniteQuery} - * for a version that fetches automatically as the user scrolls. - * - * @example - * ```tsx - * import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/preact-query' - * - * export const projectsOptions = infiniteQueryOptions({ - * queryKey: ['projects'], - * queryFn: ({ pageParam }) => fetchProjects(pageParam), - * initialPageParam: 0, - * getNextPageParam: (lastPage) => lastPage.nextId, - * }) - * - * function Projects() { - * const { data, isPending, isError, error, fetchNextPage, hasNextPage } = - * useInfiniteQuery(projectsOptions) - * - * if (isPending) return 'Loading...' - * if (isError) return Error: {error.message} - * - * return ( - *
    - *
      - * {data.pages.map((page) => page.projects.map((p) =>
    • {p.name}
    • ))} - *
    - * {hasNextPage ? ( - * - * ) : null} - *
    - * ) - * } - * ``` + * @remarks See {@link useInfiniteQuery} for examples that fetch further pages (from a button click or + * automatically as the user scrolls) and that use `skipToken` to disable the query until `postId` is set. * * @example * A parameterized factory, reused across a hook and an imperative call with the same cache entry: @@ -367,42 +301,6 @@ export function infiniteQueryOptions< * queryClient.infiniteQuery(commentsOptions(postId)).catch(noop) * ``` * - * @example - * A factory that disables the query, type safe, until `postId` is set: - * ```tsx - * import { - * infiniteQueryOptions, - * skipToken, - * useInfiniteQuery, - * } from '@tanstack/preact-query' - * - * export const commentsOptions = (postId: string | undefined) => - * infiniteQueryOptions({ - * queryKey: ['post', postId, 'comments'], - * queryFn: - * postId != null - * ? ({ pageParam }) => fetchComments(postId, pageParam) - * : skipToken, - * initialPageParam: 0, - * getNextPageParam: (lastPage) => lastPage.nextId, - * }) - * - * function Comments({ postId }: { postId: string | undefined }) { - * // Use `isLoading`, not `isPending`, so the loading state doesn't show while the query is disabled. - * const { data, isLoading, isError, error } = useInfiniteQuery(commentsOptions(postId)) - * - * if (postId == null) return 'Select a post' - * if (isLoading) return 'Loading...' - * if (isError) return Error: {error.message} - * - * return ( - *
      - * {data?.pages.map((page) => page.comments.map((c) =>
    • {c.text}
    • ))} - *
    - * ) - * } - * ``` - * * @see {@link useInfiniteQuery} to run an infinite query with these options. * @param options - The {@link UndefinedInitialDataInfiniteOptions} to use — everything you can pass to `useInfiniteQuery`. */ diff --git a/packages/preact-query/src/queryOptions.ts b/packages/preact-query/src/queryOptions.ts index a090606c96..b55ca0e14e 100644 --- a/packages/preact-query/src/queryOptions.ts +++ b/packages/preact-query/src/queryOptions.ts @@ -110,6 +110,8 @@ export type DefinedInitialDataOptions< * @see {@link useQuery} to run a query with these options. * @param options - The {@link DefinedInitialDataOptions} to use — everything you can pass to `useQuery`, with `initialData` set. * @returns The same options object, typed so that `queryKey` carries the inferred data type. + * @remarks See {@link useQuery} for more usage patterns — this factory works the same regardless of which + * overload you use. * * @example * ```tsx @@ -155,29 +157,8 @@ export function queryOptions< * @see {@link useQuery} to run a query with these options. * @param options - The {@link UnusedSkipTokenOptions} to use — everything you can pass to `useQuery`. * @returns The same options object, typed so that `queryKey` carries the inferred data type. - * - * @example - * ```tsx - * import { queryOptions, useQuery } from '@tanstack/preact-query' - * - * export const postsOptions = queryOptions({ - * queryKey: ['posts'], - * queryFn: fetchPosts, - * }) - * - * function Posts() { - * const { data, isPending, isError, error } = useQuery(postsOptions) - * - * if (isPending) return 'Loading...' - * if (isError) return Error: {error.message} - * - * return ( - *
      - * {data.map((post) =>
    • {post.title}
    • )} - *
    - * ) - * } - * ``` + * @remarks See {@link useQuery} for more usage patterns — this factory works the same regardless of which + * overload you use. * * @example * A parameterized factory, reused across a hook and an imperative call with the same cache entry: @@ -249,29 +230,8 @@ export function queryOptions< * @see {@link useQuery} to run a query with these options. * @param options - The {@link UndefinedInitialDataOptions} to use — everything you can pass to `useQuery`. * @returns The same options object, typed so that `queryKey` carries the inferred data type. - * - * @example - * ```tsx - * import { queryOptions, useQuery } from '@tanstack/preact-query' - * - * export const postsOptions = queryOptions({ - * queryKey: ['posts'], - * queryFn: fetchPosts, - * }) - * - * function Posts() { - * const { data, isPending, isError, error } = useQuery(postsOptions) - * - * if (isPending) return 'Loading...' - * if (isError) return Error: {error.message} - * - * return ( - *
      - * {data.map((post) =>
    • {post.title}
    • )} - *
    - * ) - * } - * ``` + * @remarks See {@link useQuery} for more usage patterns — this factory works the same regardless of which + * overload you use. This is the only overload that accepts `queryFn: skipToken`, shown below. * * @example * A parameterized factory, reused across a hook and an imperative call with the same cache entry: diff --git a/packages/preact-query/src/useInfiniteQuery.ts b/packages/preact-query/src/useInfiniteQuery.ts index 1be82049ba..2026ce0511 100644 --- a/packages/preact-query/src/useInfiniteQuery.ts +++ b/packages/preact-query/src/useInfiniteQuery.ts @@ -94,6 +94,45 @@ export function useInfiniteQuery< * `isFetchingPreviousPage`. * * @example + * Fetching the next page from a "Load More" button click: + * ```tsx + * import { useInfiniteQuery } from '@tanstack/preact-query' + * + * function Projects() { + * const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } = + * useInfiniteQuery({ + * queryKey: ['projects'], + * queryFn: ({ pageParam }) => fetchProjects(pageParam), + * initialPageParam: 0, + * getNextPageParam: (lastPage) => lastPage.nextId, + * }) + * + * if (isPending) return 'Loading...' + * if (isError) return Error: {error.message} + * + * return ( + * <> + *
      + * {data.pages.map((page) => + * page.projects.map((project) =>
    • {project.name}
    • ), + * )} + *
    + * + * + * ) + * } + * ``` + * + * @example * Fetching the next page automatically as the user scrolls, using an `IntersectionObserver` on a * sentinel element after the list: * ```tsx @@ -180,6 +219,45 @@ export function useInfiniteQuery< * `isFetchingPreviousPage`. * * @example + * Fetching the next page from a "Load More" button click: + * ```tsx + * import { useInfiniteQuery } from '@tanstack/preact-query' + * + * function Projects() { + * const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } = + * useInfiniteQuery({ + * queryKey: ['projects'], + * queryFn: ({ pageParam }) => fetchProjects(pageParam), + * initialPageParam: 0, + * getNextPageParam: (lastPage) => lastPage.nextId, + * }) + * + * if (isPending) return 'Loading...' + * if (isError) return Error: {error.message} + * + * return ( + * <> + *
      + * {data.pages.map((page) => + * page.projects.map((project) =>
    • {project.name}
    • ), + * )} + *
    + * + * + * ) + * } + * ``` + * + * @example * Fetching the next page automatically as the user scrolls, using an `IntersectionObserver` on a * sentinel element after the list: * ```tsx From 323487c28d309ae0b117979c0aa7692bcc38bb73 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Sun, 30 Aug 2026 12:14:38 +0900 Subject: [PATCH 26/30] docs(preact-query): remove duplicated basic-mutation example from 'mutationOptions', trim boilerplate '@remarks' --- .../reference/functions/mutationOptions.md | 25 ++++++------------- .../reference/functions/queryOptions.md | 19 +++----------- packages/preact-query/src/mutationOptions.ts | 17 ++----------- packages/preact-query/src/queryOptions.ts | 7 +----- 4 files changed, 15 insertions(+), 53 deletions(-) diff --git a/docs/framework/preact/reference/functions/mutationOptions.md b/docs/framework/preact/reference/functions/mutationOptions.md index 8d2e39f62a..018495b962 100644 --- a/docs/framework/preact/reference/functions/mutationOptions.md +++ b/docs/framework/preact/reference/functions/mutationOptions.md @@ -9,7 +9,7 @@ title: mutationOptions function mutationOptions(options): WithRequired, "mutationKey">; ``` -Defined in: [preact-query/src/mutationOptions.ts:49](https://github.com/TanStack/query/blob/main/packages/preact-query/src/mutationOptions.ts#L49) +Defined in: [preact-query/src/mutationOptions.ts:34](https://github.com/TanStack/query/blob/main/packages/preact-query/src/mutationOptions.ts#L34) You can generally pass everything to `mutationOptions` that you can also pass to `useMutation`. A `mutationKey` is required on this overload so the mutation can be looked up later, e.g. with @@ -52,21 +52,7 @@ The same options object, unchanged. [useMutation](useMutation.md) to run the mutation these options describe. -### Examples - -```tsx -import { mutationOptions, useMutation } from '@tanstack/preact-query' - -export const createPostOptions = mutationOptions({ - mutationKey: ['posts', 'create'], - mutationFn: createPost, -}) - -function CreatePost() { - const mutation = useMutation(createPostOptions) - return -} -``` +### Example Looking the mutation up elsewhere via its `mutationKey`, e.g. for a global "saving…" indicator: ```tsx @@ -92,7 +78,7 @@ function SavingIndicator() { function mutationOptions(options): Omit, "mutationKey">; ``` -Defined in: [preact-query/src/mutationOptions.ts:87](https://github.com/TanStack/query/blob/main/packages/preact-query/src/mutationOptions.ts#L87) +Defined in: [preact-query/src/mutationOptions.ts:74](https://github.com/TanStack/query/blob/main/packages/preact-query/src/mutationOptions.ts#L74) You can generally pass everything to `mutationOptions` that you can also pass to `useMutation`. No `mutationKey` is required on this overload — use this when you don't need to look the mutation up later @@ -135,6 +121,11 @@ The same options object, unchanged. [useMutation](useMutation.md) to run the mutation these options describe. +### Remarks + +Without a `mutationKey`, the mutation can't be looked up elsewhere via `useMutationState` — see +the other overload's example for that. + ### Example ```tsx diff --git a/docs/framework/preact/reference/functions/queryOptions.md b/docs/framework/preact/reference/functions/queryOptions.md index 672ca16cca..adc0d5f8e9 100644 --- a/docs/framework/preact/reference/functions/queryOptions.md +++ b/docs/framework/preact/reference/functions/queryOptions.md @@ -9,7 +9,7 @@ title: queryOptions function queryOptions(options): Omit, "queryFn"> & object & QueryKeyWithDataTag; ``` -Defined in: [preact-query/src/queryOptions.ts:142](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L142) +Defined in: [preact-query/src/queryOptions.ts:140](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L140) You can generally pass everything to `queryOptions` that you can also pass to `useQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.query`. `options.queryKey` is required and @@ -51,11 +51,6 @@ The same options object, typed so that `queryKey` carries the inferred data type [useQuery](useQuery.md) to run a query with these options. -### Remarks - -See [useQuery](useQuery.md) for more usage patterns — this factory works the same regardless of which -overload you use. - ### Example ```tsx @@ -89,7 +84,7 @@ function Posts() { function queryOptions(options): OmitKeyof, "queryFn"> & object & QueryKeyWithDataTag; ``` -Defined in: [preact-query/src/queryOptions.ts:215](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L215) +Defined in: [preact-query/src/queryOptions.ts:211](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L211) You can generally pass everything to `queryOptions` that you can also pass to `useQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.query`. `options.queryKey` is required and @@ -129,11 +124,6 @@ The same options object, typed so that `queryKey` carries the inferred data type [useQuery](useQuery.md) to run a query with these options. -### Remarks - -See [useQuery](useQuery.md) for more usage patterns — this factory works the same regardless of which -overload you use. - ### Examples A parameterized factory, reused across a hook and an imperative call with the same cache entry: @@ -192,7 +182,7 @@ queryClient.getQueryData(todosOptions.queryKey) // typed as Array | undefi function queryOptions(options): UseQueryOptions & object & QueryKeyWithDataTag; ``` -Defined in: [preact-query/src/queryOptions.ts:310](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L310) +Defined in: [preact-query/src/queryOptions.ts:305](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L305) You can generally pass everything to `queryOptions` that you can also pass to `useQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.query`. `options.queryKey` is required and @@ -234,8 +224,7 @@ The same options object, typed so that `queryKey` carries the inferred data type ### Remarks -See [useQuery](useQuery.md) for more usage patterns — this factory works the same regardless of which -overload you use. This is the only overload that accepts `queryFn: skipToken`, shown below. +This is the only overload that accepts `queryFn: skipToken`, shown below. ### Examples diff --git a/packages/preact-query/src/mutationOptions.ts b/packages/preact-query/src/mutationOptions.ts index 8763b4d903..3b9cf445d0 100644 --- a/packages/preact-query/src/mutationOptions.ts +++ b/packages/preact-query/src/mutationOptions.ts @@ -13,21 +13,6 @@ import type { UseMutationOptions } from './types' * @returns The same options object, unchanged. * * @example - * ```tsx - * import { mutationOptions, useMutation } from '@tanstack/preact-query' - * - * export const createPostOptions = mutationOptions({ - * mutationKey: ['posts', 'create'], - * mutationFn: createPost, - * }) - * - * function CreatePost() { - * const mutation = useMutation(createPostOptions) - * return - * } - * ``` - * - * @example * Looking the mutation up elsewhere via its `mutationKey`, e.g. for a global "saving…" indicator: * ```tsx * import { mutationOptions, useMutationState } from '@tanstack/preact-query' @@ -69,6 +54,8 @@ export function mutationOptions< * @param options - The mutation options to use, identical to what you'd pass to `useMutation`, without a * `mutationKey`. * @returns The same options object, unchanged. + * @remarks Without a `mutationKey`, the mutation can't be looked up elsewhere via `useMutationState` — see + * the other overload's example for that. * * @example * ```tsx diff --git a/packages/preact-query/src/queryOptions.ts b/packages/preact-query/src/queryOptions.ts index b55ca0e14e..fd04d84a49 100644 --- a/packages/preact-query/src/queryOptions.ts +++ b/packages/preact-query/src/queryOptions.ts @@ -110,8 +110,6 @@ export type DefinedInitialDataOptions< * @see {@link useQuery} to run a query with these options. * @param options - The {@link DefinedInitialDataOptions} to use — everything you can pass to `useQuery`, with `initialData` set. * @returns The same options object, typed so that `queryKey` carries the inferred data type. - * @remarks See {@link useQuery} for more usage patterns — this factory works the same regardless of which - * overload you use. * * @example * ```tsx @@ -157,8 +155,6 @@ export function queryOptions< * @see {@link useQuery} to run a query with these options. * @param options - The {@link UnusedSkipTokenOptions} to use — everything you can pass to `useQuery`. * @returns The same options object, typed so that `queryKey` carries the inferred data type. - * @remarks See {@link useQuery} for more usage patterns — this factory works the same regardless of which - * overload you use. * * @example * A parameterized factory, reused across a hook and an imperative call with the same cache entry: @@ -230,8 +226,7 @@ export function queryOptions< * @see {@link useQuery} to run a query with these options. * @param options - The {@link UndefinedInitialDataOptions} to use — everything you can pass to `useQuery`. * @returns The same options object, typed so that `queryKey` carries the inferred data type. - * @remarks See {@link useQuery} for more usage patterns — this factory works the same regardless of which - * overload you use. This is the only overload that accepts `queryFn: skipToken`, shown below. + * @remarks This is the only overload that accepts `queryFn: skipToken`, shown below. * * @example * A parameterized factory, reused across a hook and an imperative call with the same cache entry: From 53a0114998fe1dd010a5a03e4e2f1a0dcd85d54f Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Sun, 30 Aug 2026 12:18:20 +0900 Subject: [PATCH 27/30] docs(preact-query): add 'combine' example to 'useSuspenseQueries', link 'useSuspenseInfiniteQuery' to 'useInfiniteQuery' and document its waterfall/refetch risks --- .../functions/useSuspenseInfiniteQuery.md | 16 +++++++++- .../reference/functions/useSuspenseQueries.md | 31 +++++++++++++++++-- .../src/useSuspenseInfiniteQuery.ts | 8 +++++ .../preact-query/src/useSuspenseQueries.ts | 28 +++++++++++++++++ 4 files changed, 80 insertions(+), 3 deletions(-) diff --git a/docs/framework/preact/reference/functions/useSuspenseInfiniteQuery.md b/docs/framework/preact/reference/functions/useSuspenseInfiniteQuery.md index 571dc5b14d..17429a391c 100644 --- a/docs/framework/preact/reference/functions/useSuspenseInfiniteQuery.md +++ b/docs/framework/preact/reference/functions/useSuspenseInfiniteQuery.md @@ -7,7 +7,7 @@ title: useSuspenseInfiniteQuery function useSuspenseInfiniteQuery(options, queryClient?): UseSuspenseInfiniteQueryResult; ``` -Defined in: [preact-query/src/useSuspenseInfiniteQuery.ts:76](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useSuspenseInfiniteQuery.ts#L76) +Defined in: [preact-query/src/useSuspenseInfiniteQuery.ts:84](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useSuspenseInfiniteQuery.ts#L84) The options for `useSuspenseInfiniteQuery` are the same as for `useInfiniteQuery`, except for `throwOnError`, `enabled`, and `placeholderData`. @@ -59,6 +59,20 @@ The same object as `useInfiniteQuery`, except that `data` is guaranteed to be de `isPlaceholderData` is missing, and `status` is either `success` or `error` (with the derived flags set accordingly). +## Remarks + +Multiple suspenseful query calls (`useSuspenseInfiniteQuery`, `useSuspenseQuery`, etc.) in the +same component suspend serially, causing a request waterfall — each one blocks rendering until it +resolves, so the next doesn't even start fetching until then. There's no `useSuspenseInfiniteQueries` to +parallelize multiple infinite queries the way [useSuspenseQueries](useSuspenseQueries.md) does for regular ones. Also keep +in mind that imperative fetch calls, such as `fetchNextPage`, may interfere with the default refetch +behavior, resulting in outdated data. Make sure to call these functions only in response to user actions, +or add conditions like `hasNextPage && !isFetching`. + +## See + +[useInfiniteQuery](useInfiniteQuery.md) for the non-Suspense version of this hook. + ## Example ```tsx diff --git a/docs/framework/preact/reference/functions/useSuspenseQueries.md b/docs/framework/preact/reference/functions/useSuspenseQueries.md index 6ab4726a4a..f3a77c96fc 100644 --- a/docs/framework/preact/reference/functions/useSuspenseQueries.md +++ b/docs/framework/preact/reference/functions/useSuspenseQueries.md @@ -9,7 +9,7 @@ title: useSuspenseQueries function useSuspenseQueries(options, queryClient?): TCombinedResult; ``` -Defined in: [preact-query/src/useSuspenseQueries.ts:264](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useSuspenseQueries.ts#L264) +Defined in: [preact-query/src/useSuspenseQueries.ts:292](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useSuspenseQueries.ts#L292) The options for `useSuspenseQueries` are the same as for `useQueries`, except that each `query` can't have `throwOnError`, `enabled`, or `placeholderData`. @@ -129,13 +129,40 @@ function App() { } ``` +`combine`s the results into a single boolean, so `Refresh` only re-renders when that boolean changes, +not on every individual query update. This overload is the only one that accepts `combine`: +```tsx +import { Suspense } from 'preact/compat' +import { useSuspenseQueries } from '@tanstack/preact-query' + +function Refresh() { + const anyFetching = useSuspenseQueries({ + queries: [ + { queryKey: ['users'], queryFn: fetchUsers }, + { queryKey: ['teams'], queryFn: fetchTeams }, + ], + combine: (results) => results.some((result) => result.isFetching), + }) + + return anyFetching ? Refreshing… : null +} + +function App() { + return ( + Loading dashboard...}> + + + ) +} +``` + ## Call Signature ```ts function useSuspenseQueries(options, queryClient?): TCombinedResult; ``` -Defined in: [preact-query/src/useSuspenseQueries.ts:365](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useSuspenseQueries.ts#L365) +Defined in: [preact-query/src/useSuspenseQueries.ts:393](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useSuspenseQueries.ts#L393) The options for `useSuspenseQueries` are the same as for `useQueries`, except that each `query` can't have `throwOnError`, `enabled`, or `placeholderData`. diff --git a/packages/preact-query/src/useSuspenseInfiniteQuery.ts b/packages/preact-query/src/useSuspenseInfiniteQuery.ts index 8e193936d3..d2cec89a89 100644 --- a/packages/preact-query/src/useSuspenseInfiniteQuery.ts +++ b/packages/preact-query/src/useSuspenseInfiniteQuery.ts @@ -21,6 +21,14 @@ import { useBaseQuery } from './useBaseQuery' * * Caveat: cancellation does not work. * + * @remarks Multiple suspenseful query calls (`useSuspenseInfiniteQuery`, `useSuspenseQuery`, etc.) in the + * same component suspend serially, causing a request waterfall — each one blocks rendering until it + * resolves, so the next doesn't even start fetching until then. There's no `useSuspenseInfiniteQueries` to + * parallelize multiple infinite queries the way {@link useSuspenseQueries} does for regular ones. Also keep + * in mind that imperative fetch calls, such as `fetchNextPage`, may interfere with the default refetch + * behavior, resulting in outdated data. Make sure to call these functions only in response to user actions, + * or add conditions like `hasNextPage && !isFetching`. + * @see {@link useInfiniteQuery} for the non-Suspense version of this hook. * @param options - The {@link UseSuspenseInfiniteQueryOptions} to use — the same options as `useInfiniteQuery`, minus the ones listed above. * @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will * be used. diff --git a/packages/preact-query/src/useSuspenseQueries.ts b/packages/preact-query/src/useSuspenseQueries.ts index 61e886c7fe..60f84b8f90 100644 --- a/packages/preact-query/src/useSuspenseQueries.ts +++ b/packages/preact-query/src/useSuspenseQueries.ts @@ -260,6 +260,34 @@ export type SuspenseQueriesResults< * ) * } * ``` + * + * @example + * `combine`s the results into a single boolean, so `Refresh` only re-renders when that boolean changes, + * not on every individual query update. This overload is the only one that accepts `combine`: + * ```tsx + * import { Suspense } from 'preact/compat' + * import { useSuspenseQueries } from '@tanstack/preact-query' + * + * function Refresh() { + * const anyFetching = useSuspenseQueries({ + * queries: [ + * { queryKey: ['users'], queryFn: fetchUsers }, + * { queryKey: ['teams'], queryFn: fetchTeams }, + * ], + * combine: (results) => results.some((result) => result.isFetching), + * }) + * + * return anyFetching ? Refreshing… : null + * } + * + * function App() { + * return ( + * Loading dashboard...}> + * + * + * ) + * } + * ``` */ export function useSuspenseQueries< T extends Array, From a20ed3e44a185ad72fbed5c2c6eb3f4a35952753 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Sun, 30 Aug 2026 12:20:34 +0900 Subject: [PATCH 28/30] docs(preact-query): drop irrelevant 'useSuspenseQueries' reference from 'useSuspenseInfiniteQuery' waterfall remark --- .../functions/useSuspenseInfiniteQuery.md | 15 +++++++-------- .../preact-query/src/useSuspenseInfiniteQuery.ts | 13 ++++++------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/docs/framework/preact/reference/functions/useSuspenseInfiniteQuery.md b/docs/framework/preact/reference/functions/useSuspenseInfiniteQuery.md index 17429a391c..167e24c091 100644 --- a/docs/framework/preact/reference/functions/useSuspenseInfiniteQuery.md +++ b/docs/framework/preact/reference/functions/useSuspenseInfiniteQuery.md @@ -7,7 +7,7 @@ title: useSuspenseInfiniteQuery function useSuspenseInfiniteQuery(options, queryClient?): UseSuspenseInfiniteQueryResult; ``` -Defined in: [preact-query/src/useSuspenseInfiniteQuery.ts:84](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useSuspenseInfiniteQuery.ts#L84) +Defined in: [preact-query/src/useSuspenseInfiniteQuery.ts:83](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useSuspenseInfiniteQuery.ts#L83) The options for `useSuspenseInfiniteQuery` are the same as for `useInfiniteQuery`, except for `throwOnError`, `enabled`, and `placeholderData`. @@ -61,13 +61,12 @@ accordingly). ## Remarks -Multiple suspenseful query calls (`useSuspenseInfiniteQuery`, `useSuspenseQuery`, etc.) in the -same component suspend serially, causing a request waterfall — each one blocks rendering until it -resolves, so the next doesn't even start fetching until then. There's no `useSuspenseInfiniteQueries` to -parallelize multiple infinite queries the way [useSuspenseQueries](useSuspenseQueries.md) does for regular ones. Also keep -in mind that imperative fetch calls, such as `fetchNextPage`, may interfere with the default refetch -behavior, resulting in outdated data. Make sure to call these functions only in response to user actions, -or add conditions like `hasNextPage && !isFetching`. +Multiple suspenseful query calls in the same component suspend serially, causing a request +waterfall — each one blocks rendering until it resolves, so the next doesn't even start fetching until +then. There's no way to parallelize multiple infinite queries under Suspense. Also keep in mind that +imperative fetch calls, such as `fetchNextPage`, may interfere with the default refetch behavior, +resulting in outdated data. Make sure to call these functions only in response to user actions, or add +conditions like `hasNextPage && !isFetching`. ## See diff --git a/packages/preact-query/src/useSuspenseInfiniteQuery.ts b/packages/preact-query/src/useSuspenseInfiniteQuery.ts index d2cec89a89..c7c1235300 100644 --- a/packages/preact-query/src/useSuspenseInfiniteQuery.ts +++ b/packages/preact-query/src/useSuspenseInfiniteQuery.ts @@ -21,13 +21,12 @@ import { useBaseQuery } from './useBaseQuery' * * Caveat: cancellation does not work. * - * @remarks Multiple suspenseful query calls (`useSuspenseInfiniteQuery`, `useSuspenseQuery`, etc.) in the - * same component suspend serially, causing a request waterfall — each one blocks rendering until it - * resolves, so the next doesn't even start fetching until then. There's no `useSuspenseInfiniteQueries` to - * parallelize multiple infinite queries the way {@link useSuspenseQueries} does for regular ones. Also keep - * in mind that imperative fetch calls, such as `fetchNextPage`, may interfere with the default refetch - * behavior, resulting in outdated data. Make sure to call these functions only in response to user actions, - * or add conditions like `hasNextPage && !isFetching`. + * @remarks Multiple suspenseful query calls in the same component suspend serially, causing a request + * waterfall — each one blocks rendering until it resolves, so the next doesn't even start fetching until + * then. There's no way to parallelize multiple infinite queries under Suspense. Also keep in mind that + * imperative fetch calls, such as `fetchNextPage`, may interfere with the default refetch behavior, + * resulting in outdated data. Make sure to call these functions only in response to user actions, or add + * conditions like `hasNextPage && !isFetching`. * @see {@link useInfiniteQuery} for the non-Suspense version of this hook. * @param options - The {@link UseSuspenseInfiniteQueryOptions} to use — the same options as `useInfiniteQuery`, minus the ones listed above. * @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will From 66d28b7af58c1c624c551a3eaacb43b6daaa0092 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Sun, 30 Aug 2026 12:24:53 +0900 Subject: [PATCH 29/30] docs(preact-query): strengthen 'useMutation''s '@see' pointer to 'mutationOptions' with its 'mutationKey' lookup benefit --- docs/framework/preact/reference/functions/useMutation.md | 5 +++-- packages/preact-query/src/useMutation.ts | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/framework/preact/reference/functions/useMutation.md b/docs/framework/preact/reference/functions/useMutation.md index a5c6fe1939..6483a6b004 100644 --- a/docs/framework/preact/reference/functions/useMutation.md +++ b/docs/framework/preact/reference/functions/useMutation.md @@ -7,7 +7,7 @@ title: useMutation function useMutation(options, queryClient?): UseMutationResult; ``` -Defined in: [preact-query/src/useMutation.ts:190](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useMutation.ts#L190) +Defined in: [preact-query/src/useMutation.ts:191](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useMutation.ts#L191) Unlike queries, mutations are typically used to create/update/delete data or perform server side-effects. `useMutation` is the hook for that. @@ -56,7 +56,8 @@ made. ## See -[mutationOptions](mutationOptions.md) to share these options across multiple `useMutation` call sites. +[mutationOptions](mutationOptions.md) to share these options across multiple `useMutation` call sites, or to look +the mutation up elsewhere via its `mutationKey` (e.g. with `useMutationState`). ## Examples diff --git a/packages/preact-query/src/useMutation.ts b/packages/preact-query/src/useMutation.ts index bd4baf0326..eb3565732f 100644 --- a/packages/preact-query/src/useMutation.ts +++ b/packages/preact-query/src/useMutation.ts @@ -21,7 +21,8 @@ import { useSyncExternalStore } from './utils' * Unlike queries, mutations are typically used to create/update/delete data or perform server side-effects. * `useMutation` is the hook for that. * - * @see {@link mutationOptions} to share these options across multiple `useMutation` call sites. + * @see {@link mutationOptions} to share these options across multiple `useMutation` call sites, or to look + * the mutation up elsewhere via its `mutationKey` (e.g. with `useMutationState`). * @param options - The {@link UseMutationOptions} to use — everything you can pass to `useMutation`. * @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will * be used. From efa26bfddf95c8da42f17f9a36ef415ae79e8755 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Sun, 30 Aug 2026 12:47:19 +0900 Subject: [PATCH 30/30] docs(preact-query): add blank lines around 'isPending'/'isError' guards for consistency with other examples --- .../preact/reference/functions/infiniteQueryOptions.md | 8 ++++++-- docs/framework/preact/reference/functions/queryOptions.md | 8 ++++++-- .../preact/reference/functions/useInfiniteQuery.md | 4 +++- packages/preact-query/src/infiniteQueryOptions.ts | 4 ++++ packages/preact-query/src/queryOptions.ts | 4 ++++ packages/preact-query/src/useInfiniteQuery.ts | 2 ++ 6 files changed, 25 insertions(+), 5 deletions(-) diff --git a/docs/framework/preact/reference/functions/infiniteQueryOptions.md b/docs/framework/preact/reference/functions/infiniteQueryOptions.md index c7c714edea..206087481c 100644 --- a/docs/framework/preact/reference/functions/infiniteQueryOptions.md +++ b/docs/framework/preact/reference/functions/infiniteQueryOptions.md @@ -95,7 +95,7 @@ function Projects() { function infiniteQueryOptions(options): OmitKeyof, "queryFn"> & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:238](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L238) +Defined in: [preact-query/src/infiniteQueryOptions.ts:240](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L240) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -160,8 +160,10 @@ export const commentsOptions = (postId: string) => function Comments({ postId }: { postId: string }) { const { data, isPending, isError, error } = useInfiniteQuery(commentsOptions(postId)) + if (isPending) return 'Loading...' if (isError) return Error: {error.message} + return (
      {data.pages.map((page) => page.comments.map((c) =>
    • {c.text}
    • ))} @@ -185,7 +187,7 @@ queryClient.infiniteQuery(commentsOptions(postId)).catch(noop) function infiniteQueryOptions(options): UseInfiniteQueryOptions & object & QueryKeyWithDataTag, TError>; ``` -Defined in: [preact-query/src/infiniteQueryOptions.ts:307](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L307) +Defined in: [preact-query/src/infiniteQueryOptions.ts:311](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L311) You can generally pass everything to `infiniteQueryOptions` that you can also pass to `useInfiniteQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. @@ -250,8 +252,10 @@ export const commentsOptions = (postId: string) => function Comments({ postId }: { postId: string }) { const { data, isPending, isError, error } = useInfiniteQuery(commentsOptions(postId)) + if (isPending) return 'Loading...' if (isError) return Error: {error.message} + return (
        {data.pages.map((page) => page.comments.map((c) =>
      • {c.text}
      • ))} diff --git a/docs/framework/preact/reference/functions/queryOptions.md b/docs/framework/preact/reference/functions/queryOptions.md index adc0d5f8e9..4e6f33a105 100644 --- a/docs/framework/preact/reference/functions/queryOptions.md +++ b/docs/framework/preact/reference/functions/queryOptions.md @@ -84,7 +84,7 @@ function Posts() { function queryOptions(options): OmitKeyof, "queryFn"> & object & QueryKeyWithDataTag; ``` -Defined in: [preact-query/src/queryOptions.ts:211](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L211) +Defined in: [preact-query/src/queryOptions.ts:213](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L213) You can generally pass everything to `queryOptions` that you can also pass to `useQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.query`. `options.queryKey` is required and @@ -138,8 +138,10 @@ export const postOptions = (id: string) => function Post({ id }: { id: string }) { const { data, isPending, isError, error } = useQuery(postOptions(id)) + if (isPending) return 'Loading...' if (isError) return Error: {error.message} + return

        {data.title}

        } @@ -182,7 +184,7 @@ queryClient.getQueryData(todosOptions.queryKey) // typed as Array | undefi function queryOptions(options): UseQueryOptions & object & QueryKeyWithDataTag; ``` -Defined in: [preact-query/src/queryOptions.ts:305](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L305) +Defined in: [preact-query/src/queryOptions.ts:309](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L309) You can generally pass everything to `queryOptions` that you can also pass to `useQuery`. These options can be shared across hooks and imperative APIs such as `queryClient.query`. `options.queryKey` is required and @@ -240,8 +242,10 @@ export const postOptions = (id: string) => function Post({ id }: { id: string }) { const { data, isPending, isError, error } = useQuery(postOptions(id)) + if (isPending) return 'Loading...' if (isError) return Error: {error.message} + return

        {data.title}

        } diff --git a/docs/framework/preact/reference/functions/useInfiniteQuery.md b/docs/framework/preact/reference/functions/useInfiniteQuery.md index 2075ddfc47..0201330bc3 100644 --- a/docs/framework/preact/reference/functions/useInfiniteQuery.md +++ b/docs/framework/preact/reference/functions/useInfiniteQuery.md @@ -263,7 +263,7 @@ function Projects() { function useInfiniteQuery(options, queryClient?): UseInfiniteQueryResult; ``` -Defined in: [preact-query/src/useInfiniteQuery.ts:388](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L388) +Defined in: [preact-query/src/useInfiniteQuery.ts:390](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L390) The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of `queryFn`, `initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`. @@ -436,8 +436,10 @@ const commentsOptions = (postId: string) => function Comments({ postId }: { postId: string }) { const { data, isPending, isError, error } = useInfiniteQuery(commentsOptions(postId)) + if (isPending) return 'Loading...' if (isError) return Error: {error.message} + return (
          {data.pages.map((page) => page.comments.map((c) =>
        • {c.text}
        • ))} diff --git a/packages/preact-query/src/infiniteQueryOptions.ts b/packages/preact-query/src/infiniteQueryOptions.ts index 3a61ecfe7a..ece6e2c7fb 100644 --- a/packages/preact-query/src/infiniteQueryOptions.ts +++ b/packages/preact-query/src/infiniteQueryOptions.ts @@ -217,8 +217,10 @@ export function infiniteQueryOptions< * * function Comments({ postId }: { postId: string }) { * const { data, isPending, isError, error } = useInfiniteQuery(commentsOptions(postId)) + * * if (isPending) return 'Loading...' * if (isError) return Error: {error.message} + * * return ( *
            * {data.pages.map((page) => page.comments.map((c) =>
          • {c.text}
          • ))} @@ -286,8 +288,10 @@ export function infiniteQueryOptions< * * function Comments({ postId }: { postId: string }) { * const { data, isPending, isError, error } = useInfiniteQuery(commentsOptions(postId)) + * * if (isPending) return 'Loading...' * if (isError) return Error: {error.message} + * * return ( *
              * {data.pages.map((page) => page.comments.map((c) =>
            • {c.text}
            • ))} diff --git a/packages/preact-query/src/queryOptions.ts b/packages/preact-query/src/queryOptions.ts index fd04d84a49..ef9aec009f 100644 --- a/packages/preact-query/src/queryOptions.ts +++ b/packages/preact-query/src/queryOptions.ts @@ -169,8 +169,10 @@ export function queryOptions< * * function Post({ id }: { id: string }) { * const { data, isPending, isError, error } = useQuery(postOptions(id)) + * * if (isPending) return 'Loading...' * if (isError) return Error: {error.message} + * * return

              {data.title}

              * } * @@ -241,8 +243,10 @@ export function queryOptions< * * function Post({ id }: { id: string }) { * const { data, isPending, isError, error } = useQuery(postOptions(id)) + * * if (isPending) return 'Loading...' * if (isError) return Error: {error.message} + * * return

              {data.title}

              * } * diff --git a/packages/preact-query/src/useInfiniteQuery.ts b/packages/preact-query/src/useInfiniteQuery.ts index 2026ce0511..36e1514d37 100644 --- a/packages/preact-query/src/useInfiniteQuery.ts +++ b/packages/preact-query/src/useInfiniteQuery.ts @@ -332,8 +332,10 @@ export function useInfiniteQuery< * * function Comments({ postId }: { postId: string }) { * const { data, isPending, isError, error } = useInfiniteQuery(commentsOptions(postId)) + * * if (isPending) return 'Loading...' * if (isError) return Error: {error.message} + * * return ( *
                * {data.pages.map((page) => page.comments.map((c) =>
              • {c.text}
              • ))}