snapshot of https://github.com/TanStack/query.git (main, 2026-09-16; blobs > 131072B omitted)
Some checks failed
autofix.ci / autofix (push) Failing after 4s
Release / Release (push) Has been skipped
GitHub Actions Security Analysis / Run zizmor (push) Failing after 2s

This commit is contained in:
upstream-mirror
2026-09-16 01:13:08 +05:00
commit 3a013ccdfe
3570 changed files with 490194 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
---
id: HydrationBoundary
title: HydrationBoundary
---
```ts
function HydrationBoundary(__namedParameters): Element;
```
Defined in: [packages/preact-query/src/HydrationBoundary.tsx:87](https://github.com/TanStack/query/blob/main/packages/preact-query/src/HydrationBoundary.tsx#L87)
`HydrationBoundary` adds a previously dehydrated state into the `queryClient` that would be returned by
`useQueryClient()`. If the client already contains data, the new queries will be intelligently merged based on
update timestamp.
Note: Only `queries` can be dehydrated with an `HydrationBoundary`.
## Parameters
### \_\_namedParameters
[`HydrationBoundaryProps`](../interfaces/HydrationBoundaryProps.md)
## Returns
`Element`
The provided `children`, rendered unconditionally. New queries in `state` are hydrated into the
cache during render; for queries already in the cache, only newer dehydrated data is hydrated, in an effect
after commit.
## Examples
```tsx
import { HydrationBoundary } from '@tanstack/preact-query'
function App() {
return <HydrationBoundary state={dehydratedState}>...</HydrationBoundary>
}
```
Server-side prefetch handed off to the client via `dehydrate`:
```tsx
import { HydrationBoundary, dehydrate, noop } from '@tanstack/preact-query'
async function ServerComponent() {
const queryClient = getQueryClient()
await queryClient
.query({
queryKey: ['posts'],
queryFn: fetchPosts,
})
.catch(noop)
return (
<HydrationBoundary state={dehydrate(queryClient)}>
<Posts />
</HydrationBoundary>
)
}
```

View File

@@ -0,0 +1,39 @@
---
id: QueryClientProvider
title: QueryClientProvider
---
```ts
function QueryClientProvider(__namedParameters): VNode;
```
Defined in: [packages/preact-query/src/QueryClientProvider.tsx:70](https://github.com/TanStack/query/blob/main/packages/preact-query/src/QueryClientProvider.tsx#L70)
Use the `QueryClientProvider` component to connect and provide a `QueryClient` to your application. Also
calls `client.mount()`/`client.unmount()` as this component mounts/unmounts, which subscribes the client to
focus/online events (resuming any paused mutations and refetching as needed when the app regains focus or
comes back online).
## Parameters
### \_\_namedParameters
[`QueryClientProviderProps`](../type-aliases/QueryClientProviderProps.md)
## Returns
`VNode`
The provided `children`, wrapped so they can read the `QueryClient` via `useQueryClient`.
## Example
```tsx
import { QueryClient, QueryClientProvider } from '@tanstack/preact-query'
const queryClient = new QueryClient()
function App() {
return <QueryClientProvider client={queryClient}>...</QueryClientProvider>
}
```

View File

@@ -0,0 +1,68 @@
---
id: QueryErrorResetBoundary
title: QueryErrorResetBoundary
---
```ts
function QueryErrorResetBoundary(__namedParameters): Element;
```
Defined in: [packages/preact-query/src/QueryErrorResetBoundary.tsx:159](https://github.com/TanStack/query/blob/main/packages/preact-query/src/QueryErrorResetBoundary.tsx#L159)
When using `suspense` or `throwOnError` in your queries, you need a way to let queries know that you want to
try again when re-rendering after some error occurred. With the `QueryErrorResetBoundary` component you can
reset any query errors within the boundaries of the component.
## Parameters
### \_\_namedParameters
[`QueryErrorResetBoundaryProps`](../interfaces/QueryErrorResetBoundaryProps.md)
## Returns
`Element`
The `children`, rendered as-is, or called with the boundary's QueryErrorResetBoundaryValue
if `children` is a function.
## Example
```tsx
import { useErrorBoundary } from 'preact/hooks'
import type { ComponentChildren } from 'preact'
import { QueryErrorResetBoundary } from '@tanstack/preact-query'
function App() {
return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary reset={reset}>
<Page />
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
)
}
function ErrorBoundary({
children,
reset,
}: {
children: ComponentChildren
reset: () => void
}) {
const [error, resetError] = useErrorBoundary(() => reset())
if (error) {
return (
<div>
There was an error!
<button onClick={() => resetError()}>Try again</button>
</div>
)
}
return children
}
```

View File

@@ -0,0 +1,23 @@
---
id: defaultShouldDehydrateMutation
title: defaultShouldDehydrateMutation
---
```ts
function defaultShouldDehydrateMutation(mutation): boolean;
```
Defined in: [packages/query-core/src/hydration.ts:177](https://github.com/TanStack/query/blob/main/packages/query-core/src/hydration.ts#L177)
The default `shouldDehydrateMutation` predicate used by `dehydrate`. Only dehydrates mutations that are
currently paused (e.g. paused by `networkMode` while offline).
## Parameters
### mutation
[`Mutation`](../classes/Mutation.md)
## Returns
`boolean`

View File

@@ -0,0 +1,23 @@
---
id: defaultShouldDehydrateQuery
title: defaultShouldDehydrateQuery
---
```ts
function defaultShouldDehydrateQuery(query): boolean;
```
Defined in: [packages/query-core/src/hydration.ts:185](https://github.com/TanStack/query/blob/main/packages/query-core/src/hydration.ts#L185)
The default `shouldDehydrateQuery` predicate used by `dehydrate`. Only dehydrates queries whose status is
`'success'`.
## Parameters
### query
[`Query`](../classes/Query.md)
## Returns
`boolean`

View File

@@ -0,0 +1,43 @@
---
id: dehydrate
title: dehydrate
---
```ts
function dehydrate(client, options): DehydratedState;
```
Defined in: [packages/query-core/src/hydration.ts:207](https://github.com/TanStack/query/blob/main/packages/query-core/src/hydration.ts#L207)
Dehydrates a `QueryClient`'s cache (queries and mutations) into a plain, serializable `DehydratedState`,
typically to embed in server-rendered markup and later restore into a client-side `QueryClient` via `hydrate`.
Which queries/mutations are included, and how their data/errors are transformed, is controlled by `options`,
falling back to the client's `dehydrate` default options, and finally to `defaultShouldDehydrateQuery` /
`defaultShouldDehydrateMutation`.
## Parameters
### client
[`QueryClient`](../classes/QueryClient.md)
### options
[`DehydrateOptions`](../interfaces/DehydrateOptions.md) = `{}`
## Returns
[`DehydratedState`](../interfaces/DehydratedState.md)
## Example
```ts
const queryClient = new QueryClient()
await queryClient.prefetchQuery({
queryKey: ['posts'],
queryFn: getPosts,
})
const dehydratedState = dehydrate(queryClient)
```

View File

@@ -0,0 +1,43 @@
---
id: dehydrateQuery
title: dehydrateQuery
---
```ts
function dehydrateQuery(
query,
serializeData?,
shouldRedactErrors?): DehydratedQuery;
```
Defined in: [packages/query-core/src/hydration.ts:148](https://github.com/TanStack/query/blob/main/packages/query-core/src/hydration.ts#L148)
Dehydrates a single `Query` into a serializable `DehydratedQuery` snapshot. Note that most query config (e.g.
`queryFn`, `staleTime`) is not dehydrated but instead meant to be configured again when consuming the
de/rehydrated data, typically with `useQuery` on the client. If the query is still `pending`, its in-flight
promise is dehydrated too so it can be resumed on the other side instead of re-fetched.
## Parameters
### query
[`Query`](../classes/Query.md)
The query to dehydrate.
### serializeData?
`TransformerFn`
Optional transform applied to `query.state.data` before it is included in the snapshot.
### shouldRedactErrors?
(`error`) => `boolean`
Optional predicate; if it returns `false` for the promise's rejection error, that
error is kept as-is instead of being redacted.
## Returns
`DehydratedQuery`

View File

@@ -0,0 +1,52 @@
---
id: experimental_streamedQuery
title: experimental_streamedQuery
---
```ts
function experimental_streamedQuery<TQueryFnData, TData, TQueryKey>(streamFn): QueryFunction<TData, TQueryKey>;
```
Defined in: [packages/query-core/src/streamedQuery.ts:75](https://github.com/TanStack/query/blob/main/packages/query-core/src/streamedQuery.ts#L75)
This is a helper function to create a query function that streams data from an AsyncIterable.
Data will be an Array of all the chunks received.
The query will be in a 'pending' state until the first chunk of data is received, but will go to 'success' after that.
The query will stay in fetchStatus 'fetching' until the stream ends.
## Type Parameters
### TQueryFnData
`TQueryFnData` = `unknown`
### TData
`TData` = `TQueryFnData`[]
### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
## Parameters
### streamFn
`StreamedQueryParams`\<`TQueryFnData`, `TData`, `TQueryKey`\>
The function that returns an AsyncIterable to stream data from.
## Returns
[`QueryFunction`](../type-aliases/QueryFunction.md)\<`TData`, `TQueryKey`\>
## Example
```ts
await queryClient.query({
queryKey: ['data'],
queryFn: streamedQuery({
streamFn: fetchDataInChunks,
}),
})
```

View File

@@ -0,0 +1,30 @@
---
id: hashKey
title: hashKey
---
```ts
function hashKey(queryKey): string;
```
Defined in: [packages/query-core/src/utils.ts:284](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L284)
Default query & mutation keys hash function.
Hashes the value into a stable hash.
## Parameters
### queryKey
readonly `unknown`[]
## Returns
`string`
## Example
```ts
// Object keys are sorted, so key order doesn't affect the hash:
hashKey(['todos', { page: 1, filter: 'done' }]) // === '["todos",{"filter":"done","page":1}]'
```

View File

@@ -0,0 +1,49 @@
---
id: hydrate
title: hydrate
---
```ts
function hydrate(
client,
dehydratedState,
options?): void;
```
Defined in: [packages/query-core/src/hydration.ts:264](https://github.com/TanStack/query/blob/main/packages/query-core/src/hydration.ts#L264)
Restores a `DehydratedState` (as produced by `dehydrate`) into a `QueryClient`'s cache, typically to seed the
client with data already fetched on the server. `mutations` and `queries` are each optional on `dehydratedState`.
Queries not yet in the cache are built from the dehydrated snapshot; queries that already exist are only updated
when the dehydrated data is newer than what's already cached. Newly built queries have their `fetchStatus` reset
to `'idle'` so they don't hydrate stuck in a fetching state. If a dehydrated query still had an in-flight
promise, it is resumed via `query.fetch()` (reusing that promise as `initialPromise`) rather than re-invoking
`queryFn`.
## Parameters
### client
[`QueryClient`](../classes/QueryClient.md)
### dehydratedState
`Partial`\<[`DehydratedState`](../interfaces/DehydratedState.md)\>
### options?
[`HydrateOptions`](../interfaces/HydrateOptions.md)
## Returns
`void`
## Example
```ts
// dehydratedState was produced by `dehydrate` on the server
// and sent to the client, e.g. embedded in server-rendered markup.
const queryClient = new QueryClient()
hydrate(queryClient, dehydratedState)
```

View File

@@ -0,0 +1,256 @@
---
id: infiniteQueryOptions
title: infiniteQueryOptions
---
## Call Signature
```ts
function infiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options): UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam> & object & QueryKeyWithDataTag<TQueryKey, InfiniteData<TQueryFnData, unknown>, TError>;
```
Defined in: [packages/preact-query/src/infiniteQueryOptions.ts:171](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L171)
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`.
`options.queryKey` is required and is the query key to generate options for.
This overload is selected when `initialData` is set.
### Type Parameters
#### TQueryFnData
`TQueryFnData`
#### TError
`TError` = `Error`
#### TData
`TData` = [`InfiniteData`](../interfaces/InfiniteData.md)\<`TQueryFnData`, `unknown`\>
#### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
#### TPageParam
`TPageParam` = `unknown`
### Parameters
#### options
[`DefinedInitialDataInfiniteOptions`](../type-aliases/DefinedInitialDataInfiniteOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
The [DefinedInitialDataInfiniteOptions](../type-aliases/DefinedInitialDataInfiniteOptions.md) 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.
### See
[useInfiniteQuery](useInfiniteQuery.md) to run an infinite query with these options.
### Remarks
See [useInfiniteQuery](useInfiniteQuery.md) for examples that fetch further pages, from a button click or
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,
initialData: { pages: [], pageParams: [] },
})
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)
return (
<div>
{isError ? <span>Error: {error.message}</span> : null}
<ul>
{data.pages.map((page) => page.projects.map((p) => <li key={p.id}>{p.name}</li>))}
</ul>
</div>
)
}
```
## Call Signature
```ts
function infiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options): OmitKeyof<UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>, "queryFn"> & object & QueryKeyWithDataTag<TQueryKey, InfiniteData<TQueryFnData, unknown>, TError>;
```
Defined in: [packages/preact-query/src/infiniteQueryOptions.ts:233](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L233)
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`.
`options.queryKey` is required and is the query key to generate options for.
### Type Parameters
#### TQueryFnData
`TQueryFnData`
#### TError
`TError` = `Error`
#### TData
`TData` = [`InfiniteData`](../interfaces/InfiniteData.md)\<`TQueryFnData`, `unknown`\>
#### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
#### TPageParam
`TPageParam` = `unknown`
### Parameters
#### options
[`UnusedSkipTokenInfiniteOptions`](../type-aliases/UnusedSkipTokenInfiniteOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
The [UnusedSkipTokenInfiniteOptions](../type-aliases/UnusedSkipTokenInfiniteOptions.md) to use — everything you can pass to `useInfiniteQuery`.
### Returns
The same options object, typed so that `queryKey` carries the inferred data type.
### Remarks
See [useInfiniteQuery](useInfiniteQuery.md) for examples that fetch further pages, from a button click or
automatically as the user scrolls.
### Example
A parameterized factory, so the same options object can be reused per `postId`:
```tsx
import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/preact-query'
export const commentsOptions = (postId: string) =>
infiniteQueryOptions({
queryKey: ['post', postId, 'comments'],
queryFn: ({ pageParam }) => fetchComments(postId, pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
})
function Comments({ postId }: { postId: string }) {
const { data, isPending, isError, error } = useInfiniteQuery(commentsOptions(postId))
if (isPending) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return (
<ul>
{data.pages.map((page) => page.comments.map((c) => <li key={c.id}>{c.text}</li>))}
</ul>
)
}
```
### See
[useInfiniteQuery](useInfiniteQuery.md) to run an infinite query with these options.
## Call Signature
```ts
function infiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options): UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam> & object & QueryKeyWithDataTag<TQueryKey, InfiniteData<TQueryFnData, unknown>, TError>;
```
Defined in: [packages/preact-query/src/infiniteQueryOptions.ts:295](https://github.com/TanStack/query/blob/main/packages/preact-query/src/infiniteQueryOptions.ts#L295)
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`.
`options.queryKey` is required and is the query key to generate options for.
### Type Parameters
#### TQueryFnData
`TQueryFnData`
#### TError
`TError` = `Error`
#### TData
`TData` = [`InfiniteData`](../interfaces/InfiniteData.md)\<`TQueryFnData`, `unknown`\>
#### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
#### TPageParam
`TPageParam` = `unknown`
### Parameters
#### options
[`UndefinedInitialDataInfiniteOptions`](../type-aliases/UndefinedInitialDataInfiniteOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
The [UndefinedInitialDataInfiniteOptions](../type-aliases/UndefinedInitialDataInfiniteOptions.md) to use — everything you can pass to `useInfiniteQuery`.
### Returns
The same options object, typed so that `queryKey` carries the inferred data type.
### Remarks
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.
### Example
A parameterized factory, so the same options object can be reused per `postId`:
```tsx
import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/preact-query'
export const commentsOptions = (postId: string) =>
infiniteQueryOptions({
queryKey: ['post', postId, 'comments'],
queryFn: ({ pageParam }) => fetchComments(postId, pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
})
function Comments({ postId }: { postId: string }) {
const { data, isPending, isError, error } = useInfiniteQuery(commentsOptions(postId))
if (isPending) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return (
<ul>
{data.pages.map((page) => page.comments.map((c) => <li key={c.id}>{c.text}</li>))}
</ul>
)
}
```
### See
[useInfiniteQuery](useInfiniteQuery.md) to run an infinite query with these options.

View File

@@ -0,0 +1,24 @@
---
id: isCancelledError
title: isCancelledError
---
```ts
function isCancelledError(value): value is CancelledError;
```
Defined in: [packages/query-core/src/retryer.ts:90](https://github.com/TanStack/query/blob/main/packages/query-core/src/retryer.ts#L90)
## Parameters
### value
`any`
## Returns
`value is CancelledError`
## Deprecated
Use instanceof `CancelledError` instead.

View File

@@ -0,0 +1,40 @@
---
id: keepPreviousData
title: keepPreviousData
---
```ts
function keepPreviousData<T>(previousData): T | undefined;
```
Defined in: [packages/query-core/src/utils.ts:493](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L493)
Intended to be passed as a query's `placeholderData` option, for example
`placeholderData: keepPreviousData`. Instead of resetting the query's data to `undefined` while a new
query key is fetching, it keeps displaying the previously fetched data until the new data arrives.
## Type Parameters
### T
`T`
## Parameters
### previousData
`T` | `undefined`
## Returns
`T` \| `undefined`
## Example
```ts
new QueryObserver(queryClient, {
queryKey: ['posts', page],
queryFn: () => fetchPosts(page),
placeholderData: keepPreviousData,
})
```

View File

@@ -0,0 +1,38 @@
---
id: matchMutation
title: matchMutation
---
```ts
function matchMutation(filters, mutation): boolean;
```
Defined in: [packages/query-core/src/utils.ts:237](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L237)
Checks whether a mutation matches the given [MutationFilters](../interfaces/MutationFilters.md).
Every filter that is specified must match; filters that are left unspecified are ignored.
If a `mutationKey` filter is provided but the mutation has no `mutationKey` of its own, it does not match.
## Parameters
### filters
[`MutationFilters`](../interfaces/MutationFilters.md)
### mutation
[`Mutation`](../classes/Mutation.md)\<`any`, `any`\>
## Returns
`boolean`
## Example
```ts
const mutationCache = queryClient.getMutationCache()
const matchingMutations = mutationCache
.getAll()
.filter((mutation) => matchMutation({ mutationKey: ['addPost'] }, mutation))
```

View File

@@ -0,0 +1,37 @@
---
id: matchQuery
title: matchQuery
---
```ts
function matchQuery(filters, query): boolean;
```
Defined in: [packages/query-core/src/utils.ts:175](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L175)
Checks whether a query matches the given [QueryFilters](../interfaces/QueryFilters.md).
Every filter that is specified must match; filters that are left unspecified are ignored.
## Parameters
### filters
[`QueryFilters`](../interfaces/QueryFilters.md)
### query
[`Query`](../classes/Query.md)\<`any`, `any`, `any`, `any`\>
## Returns
`boolean`
## Example
```ts
const queryCache = queryClient.getQueryCache()
const matchingQueries = queryCache
.getAll()
.filter((query) => matchQuery({ queryKey: ['posts'] }, query))
```

View File

@@ -0,0 +1,142 @@
---
id: mutationOptions
title: mutationOptions
---
## Call Signature
```ts
function mutationOptions<TData, TError, TVariables, TOnMutateResult>(options): WithRequired<UseMutationOptions<TData, TError, TVariables, TOnMutateResult>, "mutationKey">;
```
Defined in: [packages/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
`useMutationState`.
### Type Parameters
#### TData
`TData` = `unknown`
#### TError
`TError` = `Error`
#### TVariables
`TVariables` = `void`
#### TOnMutateResult
`TOnMutateResult` = `unknown`
### Parameters
#### options
[`WithRequired`](../type-aliases/WithRequired.md)\<[`UseMutationOptions`](../interfaces/UseMutationOptions.md)\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>, `"mutationKey"`\>
The mutation options to use, identical to what you'd pass to `useMutation`, with a
required `mutationKey`.
### Returns
[`WithRequired`](../type-aliases/WithRequired.md)\<[`UseMutationOptions`](../interfaces/UseMutationOptions.md)\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>, `"mutationKey"`\>
The same options object, unchanged.
### See
[useMutation](useMutation.md) to run the mutation these options describe.
### Example
Looking the mutation up elsewhere via its `mutationKey`, e.g. for a global "saving…" indicator:
```tsx
import { mutationOptions, useMutationState } from '@tanstack/preact-query'
const createPostOptions = mutationOptions({
mutationKey: ['posts', 'create'],
mutationFn: createPost,
})
function SavingIndicator() {
const isCreatingPost = useMutationState({
filters: { mutationKey: createPostOptions.mutationKey, status: 'pending' },
}).length > 0
return isCreatingPost ? <span>Saving…</span> : null
}
```
## Call Signature
```ts
function mutationOptions<TData, TError, TVariables, TOnMutateResult>(options): Omit<UseMutationOptions<TData, TError, TVariables, TOnMutateResult>, "mutationKey">;
```
Defined in: [packages/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 target the mutation via a
`mutationKey` filter later (e.g. with `useMutationState`); it can still be observed through other filters,
such as `status`.
### Type Parameters
#### TData
`TData` = `unknown`
#### TError
`TError` = `Error`
#### TVariables
`TVariables` = `void`
#### TOnMutateResult
`TOnMutateResult` = `unknown`
### Parameters
#### options
`Omit`\<[`UseMutationOptions`](../interfaces/UseMutationOptions.md)\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>, `"mutationKey"`\>
The mutation options to use, identical to what you'd pass to `useMutation`, without a
`mutationKey`.
### Returns
`Omit`\<[`UseMutationOptions`](../interfaces/UseMutationOptions.md)\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>, `"mutationKey"`\>
The same options object, unchanged.
### See
[useMutation](useMutation.md) to run the mutation these options describe.
### Remarks
See the other overload's example for looking a mutation up via `useMutationState`.
### Example
```tsx
import { mutationOptions, useMutation } from '@tanstack/preact-query'
export const createPostOptions = mutationOptions({
mutationFn: createPost,
})
function CreatePost() {
const mutation = useMutation(createPostOptions)
return <button onClick={() => mutation.mutate({ title: 'Hello' })}>Create</button>
}
```

View File

@@ -0,0 +1,32 @@
---
id: noop
title: noop
---
## Call Signature
```ts
function noop(): void;
```
Defined in: [packages/query-core/src/utils.ts:119](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L119)
A function that does nothing.
### Returns
`void`
## Call Signature
```ts
function noop(): undefined;
```
Defined in: [packages/query-core/src/utils.ts:120](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L120)
A function that does nothing.
### Returns
`undefined`

View File

@@ -0,0 +1,26 @@
---
id: partialMatchKey
title: partialMatchKey
---
```ts
function partialMatchKey(a, b): boolean;
```
Defined in: [packages/query-core/src/utils.ts:300](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L300)
Checks if key `b` partially matches with key `a`.
## Parameters
### a
readonly `unknown`[]
### b
readonly `unknown`[]
## Returns
`boolean`

View File

@@ -0,0 +1,243 @@
---
id: queryOptions
title: queryOptions
---
## Call Signature
```ts
function queryOptions<TQueryFnData, TError, TData, TQueryKey>(options): Omit<UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>, "queryFn"> & object & QueryKeyWithDataTag<TQueryKey, TQueryFnData, TError>;
```
Defined in: [packages/preact-query/src/queryOptions.ts:143](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L143)
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
is the query key to generate options for.
This overload is selected when `initialData` is set, so the resulting `data` is never `undefined`.
### Type Parameters
#### TQueryFnData
`TQueryFnData` = `unknown`
#### TError
`TError` = `Error`
#### TData
`TData` = `TQueryFnData`
#### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
### Parameters
#### options
[`DefinedInitialDataOptions`](../type-aliases/DefinedInitialDataOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
The [DefinedInitialDataOptions](../type-aliases/DefinedInitialDataOptions.md) 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.
### See
- [useQuery](useQuery.md) to run a query with these options.
- [The Query Options API](https://tkdodo.eu/blog/the-query-options-api) for more on this pattern.
### Example
```tsx
import { queryOptions, useQuery } from '@tanstack/preact-query'
export const postsOptions = queryOptions({
queryKey: ['posts'],
queryFn: fetchPosts,
initialData: [],
})
function Posts() {
// `data` is `Post[]`, never `undefined`, thanks to `initialData` — even if a refetch fails,
// so the list stays visible alongside the error.
const { data, isError, error } = useQuery(postsOptions)
return (
<div>
{isError ? <span>Error: {error.message}</span> : null}
<ul>
{data.map((post) => <li key={post.id}>{post.title}</li>)}
</ul>
</div>
)
}
```
## Call Signature
```ts
function queryOptions<TQueryFnData, TError, TData, TQueryKey>(options): OmitKeyof<UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>, "queryFn"> & object & QueryKeyWithDataTag<TQueryKey, TQueryFnData, TError>;
```
Defined in: [packages/preact-query/src/queryOptions.ts:184](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L184)
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
is the query key to generate options for.
### Type Parameters
#### TQueryFnData
`TQueryFnData` = `unknown`
#### TError
`TError` = `Error`
#### TData
`TData` = `TQueryFnData`
#### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
### Parameters
#### options
[`UnusedSkipTokenOptions`](../type-aliases/UnusedSkipTokenOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
The [UnusedSkipTokenOptions](../type-aliases/UnusedSkipTokenOptions.md) to use — everything you can pass to `useQuery`.
### Returns
The same options object, typed so that `queryKey` carries the inferred data type.
### See
- [useQuery](useQuery.md) to run a query with these options.
- [The Query Options API](https://tkdodo.eu/blog/the-query-options-api) for more on this pattern.
### Example
A parameterized factory, so the same options object can be reused per `id`:
```tsx
import { queryOptions, useQuery } from '@tanstack/preact-query'
export const postOptions = (id: string) =>
queryOptions({
queryKey: ['post', id],
queryFn: () => fetchPost(id),
})
function Post({ id }: { id: string }) {
const { data, isPending, isError, error } = useQuery(postOptions(id))
if (isPending) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return <h1>{data.title}</h1>
}
```
## Call Signature
```ts
function queryOptions<TQueryFnData, TError, TData, TQueryKey>(options): UseQueryOptions<TQueryFnData, TError, TData, TQueryKey> & object & QueryKeyWithDataTag<TQueryKey, TQueryFnData, TError>;
```
Defined in: [packages/preact-query/src/queryOptions.ts:248](https://github.com/TanStack/query/blob/main/packages/preact-query/src/queryOptions.ts#L248)
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
is the query key to generate options for.
### Type Parameters
#### TQueryFnData
`TQueryFnData` = `unknown`
#### TError
`TError` = `Error`
#### TData
`TData` = `TQueryFnData`
#### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
### Parameters
#### options
[`UndefinedInitialDataOptions`](../type-aliases/UndefinedInitialDataOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
The [UndefinedInitialDataOptions](../type-aliases/UndefinedInitialDataOptions.md) to use — everything you can pass to `useQuery`.
### Returns
The same options object, typed so that `queryKey` carries the inferred data type.
### See
- [useQuery](useQuery.md) to run a query with these options.
- [The Query Options API](https://tkdodo.eu/blog/the-query-options-api) for more on this pattern.
### Remarks
This is the only overload that accepts `queryFn: skipToken`, shown below.
### Examples
A parameterized factory, so the same options object can be reused per `id`:
```tsx
import { queryOptions, useQuery } from '@tanstack/preact-query'
export const postOptions = (id: string) =>
queryOptions({
queryKey: ['post', id],
queryFn: () => fetchPost(id),
})
function Post({ id }: { id: string }) {
const { data, isPending, isError, error } = useQuery(postOptions(id))
if (isPending) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return <h1>{data.title}</h1>
}
```
A factory that disables the query, type safe, until `postId` is set:
```tsx
import { queryOptions, skipToken, useQuery } from '@tanstack/preact-query'
export const postOptions = (postId: number | undefined) =>
queryOptions({
queryKey: ['post', postId],
queryFn: postId != null ? () => fetchPost(postId) : skipToken,
})
function Post({ postId }: { postId: number | undefined }) {
const { data, isLoading, isError, error } = useQuery(postOptions(postId))
if (postId == null) return 'Select a post'
if (isLoading) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return <h1>{data?.title}</h1>
}
```

View File

@@ -0,0 +1,41 @@
---
id: replaceEqualDeep
title: replaceEqualDeep
---
```ts
function replaceEqualDeep<T>(
a,
b,
depth?): T;
```
Defined in: [packages/query-core/src/utils.ts:339](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L339)
This function returns `a` if `b` is deeply equal.
If not, it will replace any deeply equal children of `b` with those of `a`.
This can be used for structural sharing between JSON values for example.
## Type Parameters
### T
`T`
## Parameters
### a
`unknown`
### b
`T`
### depth?
`number`
## Returns
`T`

View File

@@ -0,0 +1,45 @@
---
id: shouldThrowError
title: shouldThrowError
---
```ts
function shouldThrowError<T>(throwOnError, params): boolean;
```
Defined in: [packages/query-core/src/utils.ts:576](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L576)
Resolves a `throwOnError` option to a boolean.
If `throwOnError` is a function, it is called with `params` (e.g. the error and, depending on the caller,
additional context such as the query or mutation) and its result is returned, allowing the throwing
behavior to be decided per error. Otherwise, `throwOnError` itself is coerced to a boolean (`undefined`
resolves to `false`).
## Type Parameters
### T
`T` *extends* (...`args`) => `boolean`
## Parameters
### throwOnError
`boolean` | `T` | `undefined`
### params
`Parameters`\<`T`\>
## Returns
`boolean`
## Example
```ts
const throwOnError =
query.state.error && typeof options.throwOnError === 'function'
? shouldThrowError(options.throwOnError, [query.state.error, query])
: options.throwOnError
```

View File

@@ -0,0 +1,449 @@
---
id: useInfiniteQuery
title: useInfiniteQuery
---
## Call Signature
```ts
function useInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options, queryClient?): DefinedUseInfiniteQueryResult<TData, TError>;
```
Defined in: [packages/preact-query/src/useInfiniteQuery.ts:65](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L65)
The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of
`initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`.
This overload is selected when `initialData` is set.
### Type Parameters
#### TQueryFnData
`TQueryFnData`
#### TError
`TError` = `Error`
#### TData
`TData` = [`InfiniteData`](../interfaces/InfiniteData.md)\<`TQueryFnData`, `unknown`\>
#### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
#### TPageParam
`TPageParam` = `unknown`
### Parameters
#### options
[`DefinedInitialDataInfiniteOptions`](../type-aliases/DefinedInitialDataInfiniteOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
The [DefinedInitialDataInfiniteOptions](../type-aliases/DefinedInitialDataInfiniteOptions.md) to use — everything you can pass to `useInfiniteQuery`, with `initialData` set.
#### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
be used.
### Returns
[`DefinedUseInfiniteQueryResult`](../type-aliases/DefinedUseInfiniteQueryResult.md)\<`TData`, `TError`\>
The same properties as `useQuery`, with the addition of `fetchNextPage`, `fetchPreviousPage`,
`hasNextPage`, `hasPreviousPage`, `isFetchingNextPage`, and `isFetchingPreviousPage`. `data.pages` and
`data.pageParams` are also added, as long as a `select` doesn't change `TData` away from its default
`InfiniteData<TQueryFnData>` shape.
### Remarks
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
[infiniteQueryOptions](infiniteQueryOptions.md) to share these options between `useInfiniteQuery` and imperative APIs like `queryClient.infiniteQuery`.
### Example
```tsx
import { useInfiniteQuery } from '@tanstack/preact-query'
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({
queryKey: ['projects'],
queryFn: ({ pageParam }) => fetchProjects(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
initialData: { pages: [], pageParams: [] },
})
return (
<div>
{isError ? <span>Error: {error.message}</span> : null}
<ul>
{data.pages.map((page) => page.projects.map((p) => <li key={p.id}>{p.name}</li>))}
</ul>
</div>
)
}
```
## Call Signature
```ts
function useInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options, queryClient?): UseInfiniteQueryResult<TData, TError>;
```
Defined in: [packages/preact-query/src/useInfiniteQuery.ts:191](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L191)
The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of
`initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`.
### Type Parameters
#### TQueryFnData
`TQueryFnData`
#### TError
`TError` = `Error`
#### TData
`TData` = [`InfiniteData`](../interfaces/InfiniteData.md)\<`TQueryFnData`, `unknown`\>
#### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
#### TPageParam
`TPageParam` = `unknown`
### Parameters
#### options
[`UndefinedInitialDataInfiniteOptions`](../type-aliases/UndefinedInitialDataInfiniteOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
The [UndefinedInitialDataInfiniteOptions](../type-aliases/UndefinedInitialDataInfiniteOptions.md) to use — everything you can pass to `useInfiniteQuery`.
#### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
be used.
### Returns
[`UseInfiniteQueryResult`](../type-aliases/UseInfiniteQueryResult.md)\<`TData`, `TError`\>
The same properties as `useQuery`, with the addition of `fetchNextPage`, `fetchPreviousPage`,
`hasNextPage`, `hasPreviousPage`, `isFetchingNextPage`, and `isFetchingPreviousPage`. `data.pages` and
`data.pageParams` are also added, as long as a `select` doesn't change `TData` away from its default
`InfiniteData<TQueryFnData>` shape.
### Remarks
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
[infiniteQueryOptions](infiniteQueryOptions.md) to share these options between `useInfiniteQuery` and imperative APIs like `queryClient.infiniteQuery`.
### 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 <span>Error: {error.message}</span>
return (
<>
<ul>
{data.pages.map((page) =>
page.projects.map((project) => <li key={project.id}>{project.name}</li>),
)}
</ul>
<button
onClick={() => fetchNextPage()}
disabled={!hasNextPage || isFetching}
>
{isFetchingNextPage
? 'Loading more...'
: hasNextPage
? 'Load More'
: 'Nothing more to load'}
</button>
</>
)
}
```
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 sentinelRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const sentinel = sentinelRef.current
if (sentinel == null || !hasNextPage || isFetching) return
const observer = new IntersectionObserver(([entry]) => {
if (entry?.isIntersecting) fetchNextPage()
})
observer.observe(sentinel)
return () => observer.disconnect()
}, [hasNextPage, isFetching, fetchNextPage])
if (isPending) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return (
<>
<ul>
{data.pages.map((page) =>
page.projects.map((project) => <li key={project.id}>{project.name}</li>),
)}
</ul>
<div ref={sentinelRef}>{isFetchingNextPage ? 'Loading more...' : null}</div>
</>
)
}
```
## Call Signature
```ts
function useInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options, queryClient?): UseInfiniteQueryResult<TData, TError>;
```
Defined in: [packages/preact-query/src/useInfiniteQuery.ts:347](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useInfiniteQuery.ts#L347)
The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of
`initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`.
### Type Parameters
#### TQueryFnData
`TQueryFnData`
#### TError
`TError` = `Error`
#### TData
`TData` = [`InfiniteData`](../interfaces/InfiniteData.md)\<`TQueryFnData`, `unknown`\>
#### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
#### TPageParam
`TPageParam` = `unknown`
### Parameters
#### options
[`UseInfiniteQueryOptions`](../interfaces/UseInfiniteQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
The [UseInfiniteQueryOptions](../interfaces/UseInfiniteQueryOptions.md) to use — everything you can pass to `useInfiniteQuery`.
#### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
be used.
### Returns
[`UseInfiniteQueryResult`](../type-aliases/UseInfiniteQueryResult.md)\<`TData`, `TError`\>
The same properties as `useQuery`, with the addition of `fetchNextPage`, `fetchPreviousPage`,
`hasNextPage`, `hasPreviousPage`, `isFetchingNextPage`, and `isFetchingPreviousPage`. `data.pages` and
`data.pageParams` are also added, as long as a `select` doesn't change `TData` away from its default
`InfiniteData<TQueryFnData>` shape.
### Remarks
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
[infiniteQueryOptions](infiniteQueryOptions.md) to share these options between `useInfiniteQuery` and imperative APIs like `queryClient.infiniteQuery`.
### 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 <span>Error: {error.message}</span>
return (
<>
<ul>
{data.pages.map((page) =>
page.projects.map((project) => <li key={project.id}>{project.name}</li>),
)}
</ul>
<button
onClick={() => fetchNextPage()}
disabled={!hasNextPage || isFetching}
>
{isFetchingNextPage
? 'Loading more...'
: hasNextPage
? 'Load More'
: 'Nothing more to load'}
</button>
</>
)
}
```
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 sentinelRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const sentinel = sentinelRef.current
if (sentinel == null || !hasNextPage || isFetching) return
const observer = new IntersectionObserver(([entry]) => {
if (entry?.isIntersecting) fetchNextPage()
})
observer.observe(sentinel)
return () => observer.disconnect()
}, [hasNextPage, isFetching, fetchNextPage])
if (isPending) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return (
<>
<ul>
{data.pages.map((page) =>
page.projects.map((project) => <li key={project.id}>{project.name}</li>),
)}
</ul>
<div ref={sentinelRef}>{isFetchingNextPage ? 'Loading more...' : null}</div>
</>
)
}
```
A query that's disabled, type safe, until `postId` is set — pass `skipToken` as `queryFn`
instead of setting `enabled: false`:
```tsx
import { skipToken, useInfiniteQuery } from '@tanstack/preact-query'
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({
queryKey: ['post', postId, 'comments'],
queryFn:
postId != null
? ({ pageParam }) => fetchComments(postId, pageParam)
: skipToken,
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
})
if (postId == null) return 'Select a post'
if (isLoading) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return (
<ul>
{data?.pages.map((page) => page.comments.map((c) => <li key={c.id}>{c.text}</li>))}
</ul>
)
}
```

View File

@@ -0,0 +1,61 @@
---
id: useIsFetching
title: useIsFetching
---
```ts
function useIsFetching(filters?, queryClient?): number;
```
Defined in: [packages/preact-query/src/useIsFetching.ts:44](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useIsFetching.ts#L44)
The `useIsFetching` hook returns the `number` of the queries that your application is loading or fetching in
the background (useful for app-wide loading indicators).
## Parameters
### filters?
[`QueryFilters`](../interfaces/QueryFilters.md)\<readonly `unknown`[]\>
The [QueryFilters](../interfaces/QueryFilters.md) to narrow down the matched queries.
### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
be used.
## Returns
`number`
Will be the `number` of the queries that your application is currently loading or fetching in the
background.
## Examples
```tsx
import { useIsFetching } from '@tanstack/preact-query'
function PostsFetchingIndicator() {
// How many queries matching the posts prefix are fetching?
const isFetchingPosts = useIsFetching({ queryKey: ['posts'] })
return isFetchingPosts ? <span>Refreshing posts...</span> : null
}
```
A global loading indicator for any query fetching in the background, not just the ones on screen:
```tsx
import { useIsFetching } from '@tanstack/preact-query'
function GlobalLoadingIndicator() {
const isFetching = useIsFetching()
return isFetching ? (
<div>Queries are fetching in the background...</div>
) : null
}
```

View File

@@ -0,0 +1,47 @@
---
id: useIsMutating
title: useIsMutating
---
```ts
function useIsMutating(filters?, queryClient?): number;
```
Defined in: [packages/preact-query/src/useMutationState.ts:35](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useMutationState.ts#L35)
The `useIsMutating` hook returns the `number` of mutations that your application currently has `pending`
(useful for app-wide loading indicators).
## Parameters
### filters?
[`MutationFilters`](../interfaces/MutationFilters.md)\<`unknown`, `Error`, `unknown`, `unknown`\>
The [MutationFilters](../interfaces/MutationFilters.md) to narrow down the matched mutations.
### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
be used.
## Returns
`number`
Will be the `number` of the mutations that your application currently has `pending`.
## Example
```tsx
import { useIsMutating } from '@tanstack/preact-query'
function PostsMutatingIndicator() {
// How many mutations matching the posts prefix are in progress?
const isMutatingPosts = useIsMutating({ mutationKey: ['posts'] })
return isMutatingPosts ? <span>Saving posts...</span> : null
}
```

View File

@@ -0,0 +1,20 @@
---
id: useIsRestoring
title: useIsRestoring
---
```ts
function useIsRestoring(): boolean;
```
Defined in: [packages/preact-query/src/IsRestoringProvider.ts:13](https://github.com/TanStack/query/blob/main/packages/preact-query/src/IsRestoringProvider.ts#L13)
If you are using `PersistQueryClientProvider`, you can also use the `useIsRestoring` hook alongside it to
check if a restore is currently in progress. `useQuery` and friends also check this internally to avoid
race conditions between the restore and mounting queries.
## Returns
`boolean`
`true` while a persisted client is being restored, `false` otherwise.

View File

@@ -0,0 +1,215 @@
---
id: useMutation
title: useMutation
---
```ts
function useMutation<TData, TError, TVariables, TOnMutateResult>(options, queryClient?): UseMutationResult<TData, TError, TVariables, TOnMutateResult>;
```
Defined in: [packages/preact-query/src/useMutation.ts:192](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useMutation.ts#L192)
Unlike queries, mutations are typically used to create/update/delete data or perform server side-effects.
`useMutation` is the hook for that.
## Type Parameters
### TData
`TData` = `unknown`
### TError
`TError` = `Error`
### TVariables
`TVariables` = `void`
### TOnMutateResult
`TOnMutateResult` = `unknown`
## Parameters
### options
[`UseMutationOptions`](../interfaces/UseMutationOptions.md)\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>
The [UseMutationOptions](../interfaces/UseMutationOptions.md) to use — everything you can pass to `useMutation`.
### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
be used.
## Returns
[`UseMutationResult`](../type-aliases/UseMutationResult.md)\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>
`mutate`/`mutateAsync` also accept per-call `onSuccess`/`onError`/`onSettled` callbacks as a second
argument, useful for triggering call-site side effects (e.g. navigation) without coupling them to the shared
mutation definition. Hook-level callbacks (passed to `options`) fire for every mutation; per-call callbacks
fire only for the latest call you've made, and only while the component is still mounted — unmounting before
the mutation settles removes the subscription and prevents them from firing.
## See
[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
```tsx
import { useMutation, useQueryClient } from '@tanstack/preact-query'
function AddTodo() {
const queryClient = useQueryClient()
const addMutation = useMutation({
mutationFn: addTodo,
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
})
return (
<button
onClick={() =>
addMutation.mutate('Item', {
onError: (error) => console.error('Failed to add item:', error),
})
}
>
Add
</button>
)
}
```
Rendering the mutation's own state, rather than just firing it off:
```tsx
import { useMutation, useQueryClient } from '@tanstack/preact-query'
function AddTodo() {
const queryClient = useQueryClient()
const addMutation = useMutation({
mutationFn: addTodo,
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
})
return (
<div>
{addMutation.isPending ? (
'Adding todo...'
) : (
<>
{addMutation.isError ? (
<div>An error occurred: {addMutation.error.message}</div>
) : null}
<button onClick={() => addMutation.mutate('Item')}>Add</button>
</>
)}
</div>
)
}
```
Optimistic update via `onMutate`, rolling back on `onError`:
```tsx
import { useMutation, useQueryClient } from '@tanstack/preact-query'
function AddTodo() {
const queryClient = useQueryClient()
const addMutation = useMutation({
mutationFn: addTodo,
onMutate: async (newTodo) => {
await queryClient.cancelQueries({ queryKey: ['todos'] })
const previousTodos = queryClient.getQueryData<Array<string>>(['todos'])
queryClient.setQueryData<Array<string>>(['todos'], (old) => [
...(old ?? []),
newTodo,
])
// Passed to `onError` as `onMutateResult` if the mutation fails.
return { previousTodos }
},
onError: (_err, _newTodo, onMutateResult) => {
queryClient.setQueryData(['todos'], onMutateResult?.previousTodos)
},
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
})
return (
<button onClick={() => addMutation.mutate('Item')}>Add</button>
)
}
```
Callbacks passed per call to `mutate` only fire for the last call — `mutateAsync` gives you a
promise per call instead, so you can wait for all of them when they succeed:
```tsx
import { useMutation, useQueryClient } from '@tanstack/preact-query'
function AddTodos() {
const queryClient = useQueryClient()
const addMutation = useMutation({
mutationFn: addTodo,
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
})
async function handleAddAll(todos: Array<string>) {
try {
await Promise.all(todos.map((todo) => addMutation.mutateAsync(todo)))
} catch (error) {
console.error('Failed to add todos:', error)
}
}
return (
<button onClick={() => handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])}>
Add all
</button>
)
}
```
If some of the mutations above can fail independently of the others, and you want to know which ones
did — rather than losing that information the moment the first one rejects — swap `Promise.all` for
`Promise.allSettled`:
```tsx
import { useMutation, useQueryClient } from '@tanstack/preact-query'
function AddTodos() {
const queryClient = useQueryClient()
const addMutation = useMutation({
mutationFn: addTodo,
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
})
async function handleAddAll(todos: Array<string>) {
const addResults = await Promise.allSettled(
todos.map((todo) => addMutation.mutateAsync(todo)),
)
addResults.forEach((addResult, index) => {
if (addResult.status === 'rejected') {
console.error(`Failed to add "${todos[index]}":`, addResult.reason)
}
})
}
return (
<button onClick={() => handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])}>
Add all
</button>
)
}
```

View File

@@ -0,0 +1,107 @@
---
id: useMutationState
title: useMutationState
---
```ts
function useMutationState<TResult, TMutation>(options, queryClient?): TResult[];
```
Defined in: [packages/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](../interfaces/MutationFilters.md)) to narrow down your mutations, and `select` to transform the mutation
state.
## Type Parameters
### TResult
`TResult` = [`MutationState`](../interfaces/MutationState.md)\<`unknown`, `Error`, `unknown`, `unknown`\>
### TMutation
`TMutation` *extends* [`Mutation`](../classes/Mutation.md)\<`any`, `any`, `any`, `any`\> = `MutationTypeFromResult`\<`TResult`\>
## Parameters
### options
`MutationStateOptions`\<`TResult`, `TMutation`\> = `{}`
The `filters` to narrow down matched mutations, and an optional `select` to transform the
mutation state.
### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
be used.
## Returns
`TResult`[]
Will be an Array of whatever `select` returns for each matching mutation.
## Examples
Get all variables of all running mutations:
```tsx
import { useMutationState } from '@tanstack/preact-query'
function PendingPosts() {
const pendingVariables = useMutationState({
filters: { status: 'pending' },
select: (mutation) => mutation.state.variables,
})
return <>{pendingVariables.length} posts saving...</>
}
```
Get all data for specific mutations via the `mutationKey`:
```tsx
import { useMutation, useMutationState } from '@tanstack/preact-query'
const mutationKey = ['posts']
function Posts() {
// Some mutation that we want to get the state for
const mutation = useMutation({
mutationKey,
mutationFn: createPosts,
})
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,
})
return (
<button onClick={() => mutation.mutate(['New Post'])}>
Create post ({savedPosts.length} saved so far)
</button>
)
}
```
Access the latest successful mutation data via the `mutationKey`. Each invocation of `mutate` adds a new
entry to the mutation cache for `gcTime` milliseconds — with the `status: 'success'` filter below, check the
last item that `useMutationState` returns to get the latest successful invocation:
```tsx
import { useMutationState } from '@tanstack/preact-query'
function LatestPost() {
const savedPosts = useMutationState({
filters: { mutationKey: ['posts'], status: 'success' },
select: (mutation) => mutation.state.data,
})
const latestSavedPost = savedPosts[savedPosts.length - 1]
return <>{latestSavedPost ? 'Saved' : 'Nothing saved yet'}</>
}
```

View File

@@ -0,0 +1,92 @@
---
id: usePrefetchInfiniteQuery
title: usePrefetchInfiniteQuery
---
```ts
function usePrefetchInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options, queryClient?): void;
```
Defined in: [packages/preact-query/src/usePrefetchInfiniteQuery.tsx:51](https://github.com/TanStack/query/blob/main/packages/preact-query/src/usePrefetchInfiniteQuery.tsx#L51)
`usePrefetchInfiniteQuery` does not return anything, it should be used just to fire a prefetch during render,
before a suspense boundary that wraps a component that uses `useSuspenseInfiniteQuery`. You can pass
everything to `usePrefetchInfiniteQuery` that you can pass to `queryClient.infiniteQuery`, though
`queryKey`, `initialPageParam`, and `getNextPageParam` are always required, and `queryFn` is required unless
a default query function has been defined.
`getNextPageParam` receives both the last page of the infinite list of data and the full array of all pages,
as well as pageParam information, and should return a single variable that will be passed to your query
function as `context.pageParam`. Return `undefined` or `null` to indicate there is no next page available.
The prefetch is skipped if the query already has any cached state — including a `pending`/`error` state left
over from a previous attempt — so calling this on every render is cheap and won't refetch data that's
already there or already in flight.
## Type Parameters
### TQueryFnData
`TQueryFnData` = `unknown`
### TError
`TError` = `Error`
### TData
`TData` = `TQueryFnData`
### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
### TPageParam
`TPageParam` = `unknown`
## Parameters
### options
[`UsePrefetchInfiniteQueryOptions`](../type-aliases/UsePrefetchInfiniteQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
The [UsePrefetchInfiniteQueryOptions](../type-aliases/UsePrefetchInfiniteQueryOptions.md) to use — everything you can pass to `queryClient.infiniteQuery`.
### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
be used.
## Returns
`void`
`void` — nothing is returned.
## Example
```tsx
import { Suspense } from 'preact/compat'
import { infiniteQueryOptions, usePrefetchInfiniteQuery } from '@tanstack/preact-query'
const projectsOptions = infiniteQueryOptions({
queryKey: ['projects'],
queryFn: ({ pageParam }) => fetchProjects(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
})
function App() {
// Fire the prefetch during render, before the suspense boundary below.
usePrefetchInfiniteQuery(projectsOptions)
return (
<Suspense fallback={<h1>Loading projects...</h1>}>
<Projects />
</Suspense>
)
}
```

View File

@@ -0,0 +1,83 @@
---
id: usePrefetchQuery
title: usePrefetchQuery
---
```ts
function usePrefetchQuery<TQueryFnData, TError, TData, TQueryData, TQueryKey>(options, queryClient?): void;
```
Defined in: [packages/preact-query/src/usePrefetchQuery.tsx:42](https://github.com/TanStack/query/blob/main/packages/preact-query/src/usePrefetchQuery.tsx#L42)
`usePrefetchQuery` does not return anything, it should be used just to fire a prefetch during render, before
a suspense boundary that wraps a component that uses `useSuspenseQuery`. You can pass everything to
`usePrefetchQuery` that you can pass to `queryClient.query`, though `queryKey` is always required, and
`queryFn` is required unless a default query function has been defined.
The prefetch is skipped if the query already has any cached state — including a `pending`/`error` state left
over from a previous attempt — so calling this on every render is cheap and won't refetch data that's
already there or already in flight.
## Type Parameters
### TQueryFnData
`TQueryFnData` = `unknown`
### TError
`TError` = `Error`
### TData
`TData` = `TQueryFnData`
### TQueryData
`TQueryData` = `TQueryFnData`
### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
## Parameters
### options
[`UsePrefetchQueryOptions`](../type-aliases/UsePrefetchQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryData`, `TQueryKey`\>
The [UsePrefetchQueryOptions](../type-aliases/UsePrefetchQueryOptions.md) to use — everything you can pass to `queryClient.query`.
### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
be used.
## Returns
`void`
`void` — nothing is returned.
## Example
```tsx
import { Suspense } from 'preact/compat'
import { usePrefetchQuery } from '@tanstack/preact-query'
function App() {
// Fire the prefetch during render, before the suspense boundary below.
usePrefetchQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
})
return (
<Suspense fallback={<h1>Loading posts...</h1>}>
<Posts />
</Suspense>
)
}
```

View File

@@ -0,0 +1,138 @@
---
id: useQueries
title: useQueries
---
```ts
function useQueries<T, TCombinedResult>(__namedParameters, queryClient?): TCombinedResult;
```
Defined in: [packages/preact-query/src/useQueries.ts:302](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useQueries.ts#L302)
The `useQueries` hook can be used to fetch a variable number of queries.
The `queries` key accepts an array with query option objects mostly identical to `useQuery` — see the
`queries` parameter below for the differences. A custom `QueryClient` is supplied once, as `useQueries`' own
top-level second argument, rather than per query.
Having the same query key more than once in the array of query objects may cause some data to be shared
between queries. To avoid this, consider de-duplicating the queries and map the results back to the desired
structure.
The `combine` option can be used to combine the results of the queries into a single value. The result will
be structurally shared to be as referentially stable as possible.
## Type Parameters
### T
`T` *extends* `any`[]
### TCombinedResult
`TCombinedResult` = `T` *extends* \[\] ? \[\] : `T` *extends* \[`Head`\] ? \[`GetUseQueryResult`\<`Head`\>\] : `T` *extends* \[`Head`, `...Tails[]`\] ? \[`...Tails[]`\] *extends* \[\] ? \[\] : \[`...Tails[]`\] *extends* \[`Head`\] ? \[`GetUseQueryResult`\<`Head`\>, `GetUseQueryResult`\<`Head`\>\] : \[`...Tails[]`\] *extends* \[`Head`, `...Tails[]`\] ? \[`...Tails[]`\] *extends* \[\] ? \[\] : \[`...Tails[]`\] *extends* \[`Head`\] ? \[`GetUseQueryResult`\<`Head`\>, `GetUseQueryResult`\<`Head`\>, `GetUseQueryResult`\<`Head`\>\] : \[`...Tails[]`\] *extends* \[`Head`, `...Tails[]`\] ? \[`...(...)[]`\] *extends* \[\] ? \[\] : ... *extends* ... ? ... : ... : \[`...{ [K in (...)]: (...) }[]`\] : \[...\{ \[K in string \| number \| symbol\]: GetUseQueryResult\<Tails\[K\<(...)\>\]\> \}\[\]\] : \{ \[K in string \| number \| symbol\]: GetUseQueryResult\<T\[K\<K\>\]\> \}
## Parameters
### \_\_namedParameters
#### combine?
(`result`) => `TCombinedResult`
Use this to combine the results of the queries into a single value. The result will be structurally
shared to be as referentially stable as possible.
#### queries
\| readonly \[`T` *extends* \[\] ? \[\] : `T` *extends* \[`Head`\] ? \[`GetUseQueryOptionsForUseQueries`\<`Head`\>\] : `T` *extends* \[`Head`, `...Tails[]`\] ? \[`...Tails[]`\] *extends* \[\] ? \[\] : \[`...Tails[]`\] *extends* \[`Head`\] ? \[`GetUseQueryOptionsForUseQueries`\<`Head`\>, `GetUseQueryOptionsForUseQueries`\<`Head`\>\] : \[`...Tails[]`\] *extends* \[`Head`, `...Tails[]`\] ? \[`...(...)[]`\] *extends* \[\] ? \[\] : ... *extends* ... ? ... : ... : readonly ...[] *extends* \[`...(...)[]`\] ? \[`...(...)[]`\] : ... *extends* ... ? ... : ... : readonly `unknown`[] *extends* `T` ? `T` : `T` *extends* `UseQueryOptionsForUseQueries`\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>[] ? `UseQueryOptionsForUseQueries`\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>[] : `UseQueryOptionsForUseQueries`\<`unknown`, `Error`, `unknown`, readonly ...[]\>[]\]
\| readonly \[\{ \[K in string \| number \| symbol\]: GetUseQueryOptionsForUseQueries\<T\[K\<K\>\]\> \}\]
An array with query option objects, mostly identical to `useQuery` — except that `queryClient` and
`subscribed` aren't accepted per-query (`subscribed` is a top-level option here instead), and
`placeholderData` accepts a [QueriesPlaceholderDataFunction](../type-aliases/QueriesPlaceholderDataFunction.md), which is called with `previousData`
and `previousQuery` always `undefined`, rather than `useQuery`'s placeholder function.
#### subscribed?
`boolean`
Set this to `false` to unsubscribe this observer from updates to the query cache.
**Default Value**
```ts
true
```
### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to provide a custom `QueryClient`. Otherwise, the one from the nearest context
will be used.
## Returns
`TCombinedResult`
The combined result. Without `combine`, this is an array with all the query results, in the same
order as the input. When `combine` is provided, this is the value returned by `combine` instead.
## Examples
```tsx
import { useQueries } from '@tanstack/preact-query'
function Posts({ ids }: { ids: Array<number> }) {
const postQueries = useQueries({
queries: ids.map((id) => ({
queryKey: ['post', id],
queryFn: () => fetchPost(id),
staleTime: Infinity,
})),
})
return (
<ul>
{postQueries.map((query, index) => {
if (query.isPending) return <li key={ids[index]}>Loading...</li>
if (query.isError) return <li key={ids[index]}>Error: {query.error.message}</li>
return <li key={ids[index]}>{query.data.title}</li>
})}
</ul>
)
}
```
Combining results into a single value:
```tsx
import { useQueries } from '@tanstack/preact-query'
function Posts({ ids }: { ids: Array<number> }) {
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 (
<ul>
{data.map((post) => (
<li key={post?.id}>{post?.title}</li>
))}
</ul>
)
}
```

View File

@@ -0,0 +1,379 @@
---
id: useQuery
title: useQuery
---
## Call Signature
```ts
function useQuery<TQueryFnData, TError, TData, TQueryKey>(options, queryClient?): DefinedUseQueryResult<TData, TError>;
```
Defined in: [packages/preact-query/src/useQuery.ts:50](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useQuery.ts#L50)
This overload is selected when `initialData` is set, so the resulting `data` is never `undefined`.
### Type Parameters
#### TQueryFnData
`TQueryFnData` = `unknown`
#### TError
`TError` = `Error`
#### TData
`TData` = `TQueryFnData`
#### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
### Parameters
#### options
[`DefinedInitialDataOptions`](../type-aliases/DefinedInitialDataOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
The [DefinedInitialDataOptions](../type-aliases/DefinedInitialDataOptions.md) to use — everything you can pass to `useQuery`, with `initialData` set.
#### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
be used.
### Returns
[`DefinedUseQueryResult`](../type-aliases/DefinedUseQueryResult.md)\<`TData`, `TError`\>
The current query result, typed so that `status` is `success` — or `error` if a fetch attempt
fails while keeping the existing data (`status` never resolves to `pending` in this overload's type,
since `initialData` guarantees data upfront). `isSuccess`/`isError` are derived booleans for convenience.
### See
[queryOptions](queryOptions.md) to share these options between `useQuery` and imperative APIs like `queryClient.query`.
### Example
```tsx
import { useQuery } from '@tanstack/preact-query'
function Posts() {
// `data` is `Post[]`, never `undefined`, thanks to `initialData` — even if a refetch fails,
// so the list stays visible alongside the error.
const { data, isError, error } = useQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
initialData: [],
})
return (
<div>
{isError ? <span>Error: {error.message}</span> : null}
<ul>
{data.map((post) => <li key={post.id}>{post.title}</li>)}
</ul>
</div>
)
}
```
## Call Signature
```ts
function useQuery<TQueryFnData, TError, TData, TQueryKey>(options, queryClient?): UseQueryResult<TData, TError>;
```
Defined in: [packages/preact-query/src/useQuery.ts:117](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useQuery.ts#L117)
### Type Parameters
#### TQueryFnData
`TQueryFnData` = `unknown`
#### TError
`TError` = `Error`
#### TData
`TData` = `TQueryFnData`
#### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
### Parameters
#### options
[`UndefinedInitialDataOptions`](../type-aliases/UndefinedInitialDataOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
The [UndefinedInitialDataOptions](../type-aliases/UndefinedInitialDataOptions.md) to use — everything you can pass to `useQuery`.
#### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
be used.
### Returns
[`UseQueryResult`](../type-aliases/UseQueryResult.md)\<`TData`, `TError`\>
The current query result. `status` is `pending` if there is no cached data to display, `error` if
the last fetch attempt failed, or `success` if the query has data to display. `isPending`/`isSuccess`/`isError`
are derived booleans for convenience.
### See
[queryOptions](queryOptions.md) to share these options between `useQuery` and imperative APIs like `queryClient.query`.
### Examples
```tsx
import { useQuery } from '@tanstack/preact-query'
function Posts() {
const { status, data, error, isFetching } = useQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
})
if (status === 'pending') return 'Loading...'
if (status === 'error') return <span>Error: {error.message}</span>
return (
<div>
<ul>
{data.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
<div>{isFetching ? 'Background Updating...' : ' '}</div>
</div>
)
}
```
The same query, checking `isPending`/`isError` instead of `status` — pick whichever reads better to you:
```tsx
import { useQuery } from '@tanstack/preact-query'
function Posts() {
const { isPending, isError, data, error } = useQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
})
if (isPending) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return (
<ul>
{data.map((post) => <li key={post.id}>{post.title}</li>)}
</ul>
)
}
```
## Call Signature
```ts
function useQuery<TQueryFnData, TError, TData, TQueryKey>(options, queryClient?): UseQueryResult<TData, TError>;
```
Defined in: [packages/preact-query/src/useQuery.ts:281](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useQuery.ts#L281)
### Type Parameters
#### TQueryFnData
`TQueryFnData` = `unknown`
#### TError
`TError` = `Error`
#### TData
`TData` = `TQueryFnData`
#### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
### Parameters
#### options
[`UseQueryOptions`](../interfaces/UseQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
The [UseQueryOptions](../interfaces/UseQueryOptions.md) to use — everything you can pass to `useQuery`.
#### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
be used.
### Returns
[`UseQueryResult`](../type-aliases/UseQueryResult.md)\<`TData`, `TError`\>
The current query result. `status` is `pending` if there is no cached data to display, `error` if
the last fetch attempt failed, or `success` if the query has data to display. `isPending`/`isSuccess`/`isError`
are derived booleans for convenience.
### See
[queryOptions](queryOptions.md) to share these options between `useQuery` and imperative APIs like `queryClient.query`.
### Examples
```tsx
import { useQuery } from '@tanstack/preact-query'
function Posts() {
const { status, data, error, isFetching } = useQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
})
if (status === 'pending') return 'Loading...'
if (status === 'error') return <span>Error: {error.message}</span>
return (
<div>
<ul>
{data.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
<div>{isFetching ? 'Background Updating...' : ' '}</div>
</div>
)
}
```
`select` derives whatever `data` a component needs from the cached value, without changing what's
actually stored in the cache — the cache still holds the full `Post[]`, but `data` here is a `number`:
```tsx
import { useQuery } from '@tanstack/preact-query'
function PostCount() {
const { data, isPending, isError, error } = useQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
select: (posts) => posts.length,
})
if (isPending) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return <span>{data} posts</span>
}
```
A dependent query, only enabled once `postId` is set — use `isLoading`, not `isPending`, so the
loading state doesn't show while the query is disabled:
```tsx
import { useQuery } from '@tanstack/preact-query'
function Post({ postId }: { postId: number | undefined }) {
const { data, isLoading, isError, error } = useQuery({
queryKey: ['post', postId],
queryFn: () => fetchPost(postId!),
enabled: postId != null,
})
if (postId == null) return 'Select a post'
if (isLoading) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return <h1>{data?.title}</h1>
}
```
The same dependent query, type safe: `skipToken` disables the query without needing the
non-null assertion above, since `queryFn` is only ever called when `postId` is defined.
`refetch` doesn't work while `queryFn` is `skipToken` — use `enabled: false` instead if you
need to trigger the query manually:
```tsx
import { skipToken, useQuery } from '@tanstack/preact-query'
function Post({ postId }: { postId: number | undefined }) {
const { data, isLoading, isError, error } = useQuery({
queryKey: ['post', postId],
queryFn: postId != null ? () => fetchPost(postId) : skipToken,
})
if (postId == null) return 'Select a post'
if (isLoading) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return <h1>{data?.title}</h1>
}
```
Seeding a detail query from an already-cached list, to skip the loading state:
```tsx
import { useQuery, useQueryClient } from '@tanstack/preact-query'
function Post({ postId }: { postId: number }) {
const queryClient = useQueryClient()
const { data, isError, error } = useQuery({
queryKey: ['post', postId],
queryFn: () => fetchPost(postId),
initialData: () =>
queryClient
.getQueryData<Array<Post>>(['posts'])
?.find((post) => post.id === postId),
})
if (isError) return <span>Error: {error.message}</span>
return <h1>{data?.title}</h1>
}
```
Paginated data, keeping the previous page's data visible while the next page loads:
```tsx
import { keepPreviousData, useQuery } from '@tanstack/preact-query'
import { useState } from 'preact/hooks'
function Posts() {
const [page, setPage] = useState(0)
const { data, isPlaceholderData, isError, error } = useQuery({
queryKey: ['posts', page],
queryFn: () => fetchPosts(page),
placeholderData: keepPreviousData,
})
if (isError) return <span>Error: {error.message}</span>
return (
<div>
<ul>
{data?.map((post) => <li key={post.id}>{post.title}</li>)}
</ul>
<button
disabled={isPlaceholderData}
onClick={() => setPage((old) => old + 1)}
>
Next Page
</button>
</div>
)
}
```

View File

@@ -0,0 +1,31 @@
---
id: useQueryClient
title: useQueryClient
---
```ts
function useQueryClient(queryClient?): QueryClient;
```
Defined in: [packages/preact-query/src/QueryClientProvider.tsx:21](https://github.com/TanStack/query/blob/main/packages/preact-query/src/QueryClientProvider.tsx#L21)
The `useQueryClient` hook returns the current `QueryClient` instance.
## Parameters
### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
be used.
## Returns
[`QueryClient`](../classes/QueryClient.md)
The current `QueryClient` instance.
## Throws
If no `queryClient` argument is passed and no `QueryClientProvider` is found in the component tree.

View File

@@ -0,0 +1,43 @@
---
id: useQueryErrorResetBoundary
title: useQueryErrorResetBoundary
---
```ts
function useQueryErrorResetBoundary(): QueryErrorResetBoundaryValue;
```
Defined in: [packages/preact-query/src/QueryErrorResetBoundary.tsx:85](https://github.com/TanStack/query/blob/main/packages/preact-query/src/QueryErrorResetBoundary.tsx#L85)
This hook will reset any query errors within the closest `QueryErrorResetBoundary`. If there is no boundary
defined it will reset them globally.
## Returns
`QueryErrorResetBoundaryValue`
The boundary's QueryErrorResetBoundaryValue.
## Example
```tsx
import { useErrorBoundary } from 'preact/hooks'
import type { ComponentChildren } from 'preact'
import { useQueryErrorResetBoundary } from '@tanstack/preact-query'
function App({ children }: { children: ComponentChildren }) {
const { reset } = useQueryErrorResetBoundary()
const [error, resetError] = useErrorBoundary(() => reset())
if (error) {
return (
<div>
There was an error!
<button onClick={() => resetError()}>Try again</button>
</div>
)
}
return children
}
```

View File

@@ -0,0 +1,160 @@
---
id: useSuspenseInfiniteQuery
title: useSuspenseInfiniteQuery
---
```ts
function useSuspenseInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options, queryClient?): UseSuspenseInfiniteQueryResult<TData, TError>;
```
Defined in: [packages/preact-query/src/useSuspenseInfiniteQuery.ts:124](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useSuspenseInfiniteQuery.ts#L124)
The options for `useSuspenseInfiniteQuery` are the same as for `useInfiniteQuery`, except for `throwOnError`,
`enabled`, and `placeholderData`.
Caveat: cancellation does not work.
## Type Parameters
### TQueryFnData
`TQueryFnData`
### TError
`TError` = `Error`
### TData
`TData` = [`InfiniteData`](../interfaces/InfiniteData.md)\<`TQueryFnData`, `unknown`\>
### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
### TPageParam
`TPageParam` = `unknown`
## Parameters
### options
[`UseSuspenseInfiniteQueryOptions`](../interfaces/UseSuspenseInfiniteQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
The [UseSuspenseInfiniteQueryOptions](../interfaces/UseSuspenseInfiniteQueryOptions.md) to use — the same options as `useInfiniteQuery`, minus the ones listed above.
### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
be used.
## Returns
[`UseSuspenseInfiniteQueryResult`](../type-aliases/UseSuspenseInfiniteQueryResult.md)\<`TData`, `TError`\>
The same object as `useInfiniteQuery`, except that `data` is guaranteed to be defined,
`isPlaceholderData` is missing, and `status` is either `success` or `error` (with the derived flags set
accordingly).
## 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
[useInfiniteQuery](useInfiniteQuery.md) for the non-Suspense version of this hook.
## Example
The query error is thrown if a fetch fails and no cached data exists yet, so an error boundary is
required around `<Suspense>`. A failed background refetch instead continues to render the cached data.
Use [QueryErrorResetBoundary](QueryErrorResetBoundary.md) to let the user retry after such an error:
```tsx
import { Suspense } from 'preact/compat'
import { useErrorBoundary } from 'preact/hooks'
import {
QueryErrorResetBoundary,
useSuspenseInfiniteQuery,
} from '@tanstack/preact-query'
import type { ComponentChildren } from 'preact'
function Projects() {
// `data` is guaranteed to be defined here — no `isPending` check needed.
const { data, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } =
useSuspenseInfiniteQuery({
queryKey: ['projects'],
queryFn: ({ pageParam }) => fetchProjects(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
})
return (
<div>
<ul>
{data.pages.map((page) =>
page.projects.map((project) => <li key={project.id}>{project.name}</li>),
)}
</ul>
<button
onClick={() => fetchNextPage()}
disabled={!hasNextPage || isFetching}
>
{isFetchingNextPage
? 'Loading more...'
: hasNextPage
? 'Load More'
: 'Nothing more to load'}
</button>
</div>
)
}
function App() {
return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<div>
There was an error!
<button onClick={() => resetErrorBoundary()}>Try again</button>
</div>
)}
>
<Suspense fallback={<h1>Loading projects...</h1>}>
<Projects />
</Suspense>
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
)
}
function ErrorBoundary({
children,
onReset,
fallbackRender,
}: {
children: ComponentChildren
onReset: () => void
fallbackRender: (props: {
error: Error
resetErrorBoundary: () => void
}) => ComponentChildren
}) {
const [error, resetErrorBoundary] = useErrorBoundary(() => onReset())
if (error) return fallbackRender({ error, resetErrorBoundary })
return children
}
```

View File

@@ -0,0 +1,478 @@
---
id: useSuspenseQueries
title: useSuspenseQueries
---
## Call Signature
```ts
function useSuspenseQueries<T, TCombinedResult>(options, queryClient?): TCombinedResult;
```
Defined in: [packages/preact-query/src/useSuspenseQueries.ts:409](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useSuspenseQueries.ts#L409)
The options for `useSuspenseQueries` are the same as for `useQueries`, except that the top-level `subscribed`
option isn't supported, and each `query` can't have `throwOnError`, `enabled`, or `placeholderData`.
### Type Parameters
#### T
`T` *extends* `any`[]
#### TCombinedResult
`TCombinedResult` = `T` *extends* \[\] ? \[\] : `T` *extends* \[`Head`\] ? \[`GetUseSuspenseQueryResult`\<`Head`\>\] : `T` *extends* \[`Head`, `...Tails[]`\] ? \[`...Tails[]`\] *extends* \[\] ? \[\] : \[`...Tails[]`\] *extends* \[`Head`\] ? \[`GetUseSuspenseQueryResult`\<`Head`\>, `GetUseSuspenseQueryResult`\<`Head`\>\] : \[`...Tails[]`\] *extends* \[`Head`, `...Tails[]`\] ? \[`...Tails[]`\] *extends* \[\] ? \[\] : \[`...Tails[]`\] *extends* \[`Head`\] ? \[`GetUseSuspenseQueryResult`\<`Head`\>, `GetUseSuspenseQueryResult`\<`Head`\>, `GetUseSuspenseQueryResult`\<`Head`\>\] : \[`...Tails[]`\] *extends* \[`Head`, `...Tails[]`\] ? \[`...(...)[]`\] *extends* \[\] ? \[\] : ... *extends* ... ? ... : ... : \[`...{ [K in (...)]: (...) }[]`\] : \[...\{ \[K in string \| number \| symbol\]: GetUseSuspenseQueryResult\<Tails\[K\<(...)\>\]\> \}\[\]\] : \{ \[K in string \| number \| symbol\]: GetUseSuspenseQueryResult\<T\[K\<K\>\]\> \}
### Parameters
#### options
The `queries` array to run in Suspense, and an optional `combine` function.
##### combine?
(`result`) => `TCombinedResult`
Use this to combine the results of the queries into a single value. The result will be structurally
shared to be as referentially stable as possible.
##### queries
\| readonly \[`T` *extends* \[\] ? \[\] : `T` *extends* \[`Head`\] ? \[`GetUseSuspenseQueryOptions`\<`Head`\>\] : `T` *extends* \[`Head`, `...Tails[]`\] ? \[`...Tails[]`\] *extends* \[\] ? \[\] : \[`...Tails[]`\] *extends* \[`Head`\] ? \[`GetUseSuspenseQueryOptions`\<`Head`\>, `GetUseSuspenseQueryOptions`\<`Head`\>\] : \[`...Tails[]`\] *extends* \[`Head`, `...Tails[]`\] ? \[`...(...)[]`\] *extends* \[\] ? \[\] : ... *extends* ... ? ... : ... : ...[] *extends* \[`...(...)[]`\] ? \[`...(...)[]`\] : ... *extends* ... ? ... : ... : `unknown`[] *extends* `T` ? `T` : `T` *extends* [`UseSuspenseQueryOptions`](../interfaces/UseSuspenseQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>[] ? [`UseSuspenseQueryOptions`](../interfaces/UseSuspenseQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>[] : [`UseSuspenseQueryOptions`](../interfaces/UseSuspenseQueryOptions.md)\<`unknown`, `Error`, `unknown`, readonly ...[]\>[]\]
\| readonly \[\{ \[K in string \| number \| symbol\]: GetUseSuspenseQueryOptions\<T\[K\<K\>\]\> \}\]
An array with query option objects identical to `useSuspenseQuery`.
#### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to provide a custom `QueryClient`. Otherwise, the one from the nearest context
will be used.
### Returns
`TCombinedResult`
The same structure as `useQueries`, except that for each `query`, `data` is guaranteed to be
defined, `isPlaceholderData` is missing, and `status` is either `success` or `error` (with the derived
flags set accordingly).
Caveat: the component will only re-mount after all queries have finished loading. Hence, if a query has gone
stale in the time it took for all the queries to complete, it will be fetched again at re-mount. To avoid
this, make sure to set a high enough `staleTime`. Cancellation does not work.
### Examples
The query error is thrown if a fetch fails and no cached data exists yet, so an error boundary is
required around `<Suspense>`. A failed background refetch instead continues to render the cached data.
Use [QueryErrorResetBoundary](QueryErrorResetBoundary.md) to let the user retry after such an error:
```tsx
import { Suspense } from 'preact/compat'
import { useErrorBoundary } from 'preact/hooks'
import {
QueryErrorResetBoundary,
useSuspenseQueries,
} from '@tanstack/preact-query'
import type { ComponentChildren } from 'preact'
function Posts({ ids }: { ids: Array<number> }) {
// Every result is guaranteed to be defined — no per-query `isPending` check needed.
const postQueries = useSuspenseQueries({
queries: ids.map((id) => ({
queryKey: ['post', id],
queryFn: () => fetchPost(id),
})),
})
return (
<ul>
{postQueries.map((query) => (
<li key={query.data.id}>{query.data.title}</li>
))}
</ul>
)
}
function App() {
return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<div>
There was an error!
<button onClick={() => resetErrorBoundary()}>Try again</button>
</div>
)}
>
<Suspense fallback={<h1>Loading posts...</h1>}>
<Posts ids={[1, 2, 3]} />
</Suspense>
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
)
}
function ErrorBoundary({
children,
onReset,
fallbackRender,
}: {
children: ComponentChildren
onReset: () => void
fallbackRender: (props: {
error: Error
resetErrorBoundary: () => void
}) => ComponentChildren
}) {
const [error, resetErrorBoundary] = useErrorBoundary(() => onReset())
if (error) return fallbackRender({ error, resetErrorBoundary })
return children
}
```
Several different queries — use `useSuspenseQueries` instead of multiple `useSuspenseQuery` calls, so
they fetch in parallel rather than suspending one after another:
```tsx
import { Suspense } from 'preact/compat'
import { useErrorBoundary } from 'preact/hooks'
import {
QueryErrorResetBoundary,
useSuspenseQueries,
} from '@tanstack/preact-query'
import type { ComponentChildren } from 'preact'
function Dashboard() {
const [usersQuery, teamsQuery, projectsQuery] = useSuspenseQueries({
queries: [
{ queryKey: ['users'], queryFn: fetchUsers },
{ queryKey: ['teams'], queryFn: fetchTeams },
{ queryKey: ['projects'], queryFn: fetchProjects },
],
})
return (
<div>
<UserList users={usersQuery.data} />
<TeamList teams={teamsQuery.data} />
<ProjectList projects={projectsQuery.data} />
</div>
)
}
function App() {
return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<div>
There was an error!
<button onClick={() => resetErrorBoundary()}>Try again</button>
</div>
)}
>
<Suspense fallback={<h1>Loading dashboard...</h1>}>
<Dashboard />
</Suspense>
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
)
}
function ErrorBoundary({
children,
onReset,
fallbackRender,
}: {
children: ComponentChildren
onReset: () => void
fallbackRender: (props: {
error: Error
resetErrorBoundary: () => void
}) => ComponentChildren
}) {
const [error, resetErrorBoundary] = useErrorBoundary(() => onReset())
if (error) return fallbackRender({ error, resetErrorBoundary })
return children
}
```
`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 { useErrorBoundary } from 'preact/hooks'
import {
QueryErrorResetBoundary,
useSuspenseQueries,
} from '@tanstack/preact-query'
import type { ComponentChildren } from 'preact'
function Refresh() {
const anyFetching = useSuspenseQueries({
queries: [
{ queryKey: ['users'], queryFn: fetchUsers },
{ queryKey: ['teams'], queryFn: fetchTeams },
],
combine: (results) => results.some((result) => result.isFetching),
})
return anyFetching ? <span>Refreshing…</span> : null
}
function App() {
return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<div>
There was an error!
<button onClick={() => resetErrorBoundary()}>Try again</button>
</div>
)}
>
<Suspense fallback={<h1>Loading dashboard...</h1>}>
<Refresh />
</Suspense>
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
)
}
function ErrorBoundary({
children,
onReset,
fallbackRender,
}: {
children: ComponentChildren
onReset: () => void
fallbackRender: (props: {
error: Error
resetErrorBoundary: () => void
}) => ComponentChildren
}) {
const [error, resetErrorBoundary] = useErrorBoundary(() => onReset())
if (error) return fallbackRender({ error, resetErrorBoundary })
return children
}
```
## Call Signature
```ts
function useSuspenseQueries<T, TCombinedResult>(options, queryClient?): TCombinedResult;
```
Defined in: [packages/preact-query/src/useSuspenseQueries.ts:589](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useSuspenseQueries.ts#L589)
The options for `useSuspenseQueries` are the same as for `useQueries`, except that the top-level `subscribed`
option isn't supported, and each `query` can't have `throwOnError`, `enabled`, or `placeholderData`.
### Type Parameters
#### T
`T` *extends* `any`[]
#### TCombinedResult
`TCombinedResult` = `T` *extends* \[\] ? \[\] : `T` *extends* \[`Head`\] ? \[`GetUseSuspenseQueryResult`\<`Head`\>\] : `T` *extends* \[`Head`, `...Tails[]`\] ? \[`...Tails[]`\] *extends* \[\] ? \[\] : \[`...Tails[]`\] *extends* \[`Head`\] ? \[`GetUseSuspenseQueryResult`\<`Head`\>, `GetUseSuspenseQueryResult`\<`Head`\>\] : \[`...Tails[]`\] *extends* \[`Head`, `...Tails[]`\] ? \[`...Tails[]`\] *extends* \[\] ? \[\] : \[`...Tails[]`\] *extends* \[`Head`\] ? \[`GetUseSuspenseQueryResult`\<`Head`\>, `GetUseSuspenseQueryResult`\<`Head`\>, `GetUseSuspenseQueryResult`\<`Head`\>\] : \[`...Tails[]`\] *extends* \[`Head`, `...Tails[]`\] ? \[`...(...)[]`\] *extends* \[\] ? \[\] : ... *extends* ... ? ... : ... : \[`...{ [K in (...)]: (...) }[]`\] : \[...\{ \[K in string \| number \| symbol\]: GetUseSuspenseQueryResult\<Tails\[K\<(...)\>\]\> \}\[\]\] : \{ \[K in string \| number \| symbol\]: GetUseSuspenseQueryResult\<T\[K\<K\>\]\> \}
### Parameters
#### options
The `queries` array to run in Suspense, and an optional `combine` function.
##### combine?
(`result`) => `TCombinedResult`
Use this to combine the results of the queries into a single value. The result will be structurally
shared to be as referentially stable as possible.
##### queries
readonly \[`T` *extends* \[\] ? \[\] : `T` *extends* \[`Head`\] ? \[`GetUseSuspenseQueryOptions`\<`Head`\>\] : `T` *extends* \[`Head`, `...Tails[]`\] ? \[`...Tails[]`\] *extends* \[\] ? \[\] : \[`...Tails[]`\] *extends* \[`Head`\] ? \[`GetUseSuspenseQueryOptions`\<`Head`\>, `GetUseSuspenseQueryOptions`\<`Head`\>\] : \[`...Tails[]`\] *extends* \[`Head`, `...Tails[]`\] ? \[`...Tails[]`\] *extends* \[\] ? \[\] : \[`...(...)[]`\] *extends* \[...\] ? \[..., ..., ...\] : ... *extends* ... ? ... : ... : `unknown`[] *extends* \[`...Tails[]`\] ? \[`...Tails[]`\] : \[`...(...)[]`\] *extends* ...[] ? ...[] : ...[] : `unknown`[] *extends* `T` ? `T` : `T` *extends* [`UseSuspenseQueryOptions`](../interfaces/UseSuspenseQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>[] ? [`UseSuspenseQueryOptions`](../interfaces/UseSuspenseQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>[] : [`UseSuspenseQueryOptions`](../interfaces/UseSuspenseQueryOptions.md)\<`unknown`, `Error`, `unknown`, readonly `unknown`[]\>[]\]
An array with query option objects identical to `useSuspenseQuery`.
#### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to provide a custom `QueryClient`. Otherwise, the one from the nearest context
will be used.
### Returns
`TCombinedResult`
The same structure as `useQueries`, except that for each `query`, `data` is guaranteed to be
defined, `isPlaceholderData` is missing, and `status` is either `success` or `error` (with the derived
flags set accordingly).
Caveat: the component will only re-mount after all queries have finished loading. Hence, if a query has gone
stale in the time it took for all the queries to complete, it will be fetched again at re-mount. To avoid
this, make sure to set a high enough `staleTime`. Cancellation does not work.
### Examples
The query error is thrown if a fetch fails and no cached data exists yet, so an error boundary is
required around `<Suspense>`. A failed background refetch instead continues to render the cached data.
Use [QueryErrorResetBoundary](QueryErrorResetBoundary.md) to let the user retry after such an error:
```tsx
import { Suspense } from 'preact/compat'
import { useErrorBoundary } from 'preact/hooks'
import {
QueryErrorResetBoundary,
useSuspenseQueries,
} from '@tanstack/preact-query'
import type { ComponentChildren } from 'preact'
function Posts({ ids }: { ids: Array<number> }) {
// Every result is guaranteed to be defined — no per-query `isPending` check needed.
const postQueries = useSuspenseQueries({
queries: ids.map((id) => ({
queryKey: ['post', id],
queryFn: () => fetchPost(id),
})),
})
return (
<ul>
{postQueries.map((query) => (
<li key={query.data.id}>{query.data.title}</li>
))}
</ul>
)
}
function App() {
return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<div>
There was an error!
<button onClick={() => resetErrorBoundary()}>Try again</button>
</div>
)}
>
<Suspense fallback={<h1>Loading posts...</h1>}>
<Posts ids={[1, 2, 3]} />
</Suspense>
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
)
}
function ErrorBoundary({
children,
onReset,
fallbackRender,
}: {
children: ComponentChildren
onReset: () => void
fallbackRender: (props: {
error: Error
resetErrorBoundary: () => void
}) => ComponentChildren
}) {
const [error, resetErrorBoundary] = useErrorBoundary(() => onReset())
if (error) return fallbackRender({ error, resetErrorBoundary })
return children
}
```
Several different queries — use `useSuspenseQueries` instead of multiple `useSuspenseQuery` calls, so
they fetch in parallel rather than suspending one after another:
```tsx
import { Suspense } from 'preact/compat'
import { useErrorBoundary } from 'preact/hooks'
import {
QueryErrorResetBoundary,
useSuspenseQueries,
} from '@tanstack/preact-query'
import type { ComponentChildren } from 'preact'
function Dashboard() {
const [usersQuery, teamsQuery, projectsQuery] = useSuspenseQueries({
queries: [
{ queryKey: ['users'], queryFn: fetchUsers },
{ queryKey: ['teams'], queryFn: fetchTeams },
{ queryKey: ['projects'], queryFn: fetchProjects },
],
})
return (
<div>
<UserList users={usersQuery.data} />
<TeamList teams={teamsQuery.data} />
<ProjectList projects={projectsQuery.data} />
</div>
)
}
function App() {
return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<div>
There was an error!
<button onClick={() => resetErrorBoundary()}>Try again</button>
</div>
)}
>
<Suspense fallback={<h1>Loading dashboard...</h1>}>
<Dashboard />
</Suspense>
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
)
}
function ErrorBoundary({
children,
onReset,
fallbackRender,
}: {
children: ComponentChildren
onReset: () => void
fallbackRender: (props: {
error: Error
resetErrorBoundary: () => void
}) => ComponentChildren
}) {
const [error, resetErrorBoundary] = useErrorBoundary(() => onReset())
if (error) return fallbackRender({ error, resetErrorBoundary })
return children
}
```

View File

@@ -0,0 +1,134 @@
---
id: useSuspenseQuery
title: useSuspenseQuery
---
```ts
function useSuspenseQuery<TQueryFnData, TError, TData, TQueryKey>(options, queryClient?): UseSuspenseQueryResult<TData, TError>;
```
Defined in: [packages/preact-query/src/useSuspenseQuery.ts:95](https://github.com/TanStack/query/blob/main/packages/preact-query/src/useSuspenseQuery.ts#L95)
The options for `useSuspenseQuery` are the same as for `useQuery`, except for `throwOnError`, `enabled`, and
`placeholderData`.
Caveat: cancellation does not work.
## Type Parameters
### TQueryFnData
`TQueryFnData` = `unknown`
### TError
`TError` = `Error`
### TData
`TData` = `TQueryFnData`
### TQueryKey
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
## Parameters
### options
[`UseSuspenseQueryOptions`](../interfaces/UseSuspenseQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
The [UseSuspenseQueryOptions](../interfaces/UseSuspenseQueryOptions.md) to use — the same options as `useQuery`, minus the ones listed above.
### queryClient?
[`QueryClient`](../classes/QueryClient.md)
Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
be used.
## Returns
[`UseSuspenseQueryResult`](../type-aliases/UseSuspenseQueryResult.md)\<`TData`, `TError`\>
The same object as `useQuery`, except that `data` is guaranteed to be defined, `isPlaceholderData`
is missing, and `status` is either `success` or `error` (with the derived flags set accordingly).
## Remarks
Multiple `useSuspenseQuery` 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.
Use [useSuspenseQueries](useSuspenseQueries.md) instead when you have more than one suspenseful query in a component, so they
fetch in parallel.
## Example
The query error is thrown if the fetch fails and no cached data exists yet, so an error boundary is
required around `<Suspense>`. A failed background refetch instead continues to render the cached data.
Use [QueryErrorResetBoundary](QueryErrorResetBoundary.md) to let the user retry after such an error:
```tsx
import { Suspense } from 'preact/compat'
import { useErrorBoundary } from 'preact/hooks'
import { QueryErrorResetBoundary, useSuspenseQuery } from '@tanstack/preact-query'
import type { ComponentChildren } from 'preact'
function Posts() {
// `data` is guaranteed to be defined here — no `isPending` check needed.
const { data, isFetching } = useSuspenseQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
})
return (
<div>
<h1>Posts {isFetching ? '(refreshing...)' : null}</h1>
<ul>
{data.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
)
}
function App() {
return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<div>
There was an error!
<button onClick={() => resetErrorBoundary()}>Try again</button>
</div>
)}
>
<Suspense fallback={<h1>Loading posts...</h1>}>
<Posts />
</Suspense>
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
)
}
function ErrorBoundary({
children,
onReset,
fallbackRender,
}: {
children: ComponentChildren
onReset: () => void
fallbackRender: (props: {
error: Error
resetErrorBoundary: () => void
}) => ComponentChildren
}) {
const [error, resetErrorBoundary] = useErrorBoundary(() => onReset())
if (error) return fallbackRender({ error, resetErrorBoundary })
return children
}
```