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,39 @@
---
id: QueryClientProvider
title: QueryClientProvider
---
```ts
function QueryClientProvider(props): Element;
```
Defined in: [packages/solid-query/src/QueryClientProvider.tsx:95](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClientProvider.tsx#L95)
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
### props
[`QueryClientProviderProps`](../type-aliases/QueryClientProviderProps.md)
## Returns
`Element`
The provided `children`, wrapped so they can read the `QueryClient` via `useQueryClient`.
## Example
```tsx
import { QueryClient, QueryClientProvider } from '@tanstack/solid-query'
const queryClient = new QueryClient()
function App() {
return <QueryClientProvider client={queryClient}>...</QueryClientProvider>
}
```

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`
### 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`
### 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,178 @@
---
id: infiniteQueryOptions
title: infiniteQueryOptions
redirect_from:
- framework/solid/reference/infiniteQueryOptions
---
## Call Signature
```ts
function infiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options): InfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam> & object & QueryKeyWithDataTag<TQueryKey, InfiniteData<TQueryFnData, unknown>, TError>;
```
Defined in: [packages/solid-query/src/infiniteQueryOptions.ts:105](https://github.com/TanStack/query/blob/main/packages/solid-query/src/infiniteQueryOptions.ts#L105)
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
[`InfiniteQueryOptions`](../interfaces/InfiniteQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\> & `object`
The [DefinedInitialDataInfiniteOptions](../type-aliases/DefinedInitialDataInfiniteOptions.md) to use — everything you can pass to `useInfiniteQuery`, with `initialData` set.
### Returns
[`InfiniteQueryOptions`](../interfaces/InfiniteQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\> & `object` & [`QueryKeyWithDataTag`](../type-aliases/QueryKeyWithDataTag.md)\<`TQueryKey`, [`InfiniteData`](../interfaces/InfiniteData.md)\<`TQueryFnData`, `unknown`\>, `TError`\>
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.
### Example
```tsx
import { For } from 'solid-js'
import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/solid-query'
const projectsOptions = infiniteQueryOptions({
queryKey: ['projects'],
queryFn: ({ pageParam }) => fetchProjects(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
initialData: { pages: [], pageParams: [] },
})
function Projects() {
// `projectsQuery.data` is never `undefined`, thanks to `initialData` — even if a refetch fails, so the
// list stays visible alongside the error.
const projectsQuery = useInfiniteQuery(() => projectsOptions)
return (
<div>
{projectsQuery.isError ? <span>Error: {projectsQuery.error.message}</span> : null}
<ul>
<For each={projectsQuery.data.pages}>
{(page) => <For each={page.projects}>{(p) => <li>{p.name}</li>}</For>}
</For>
</ul>
</div>
)
}
```
## Call Signature
```ts
function infiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options): InfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam> & object & QueryKeyWithDataTag<TQueryKey, InfiniteData<TQueryFnData, unknown>, TError>;
```
Defined in: [packages/solid-query/src/infiniteQueryOptions.ts:174](https://github.com/TanStack/query/blob/main/packages/solid-query/src/infiniteQueryOptions.ts#L174)
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
[`InfiniteQueryOptions`](../interfaces/InfiniteQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\> & `object`
The [UndefinedInitialDataInfiniteOptions](../type-aliases/UndefinedInitialDataInfiniteOptions.md) to use — everything you can pass to `useInfiniteQuery`.
### Returns
[`InfiniteQueryOptions`](../interfaces/InfiniteQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\> & `object` & [`QueryKeyWithDataTag`](../type-aliases/QueryKeyWithDataTag.md)\<`TQueryKey`, [`InfiniteData`](../interfaces/InfiniteData.md)\<`TQueryFnData`, `unknown`\>, `TError`\>
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.
### Example
A parameterized factory, so the same options object can be reused per `postId`:
```tsx
import { For, Match, Switch } from 'solid-js'
import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/solid-query'
const commentsOptions = (postId: string) =>
infiniteQueryOptions({
queryKey: ['post', postId, 'comments'],
queryFn: ({ pageParam }) => fetchComments(postId, pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
})
function Comments(props: { postId: string }) {
const commentsQuery = useInfiniteQuery(() => commentsOptions(props.postId))
return (
<Switch>
<Match when={commentsQuery.isPending}>Loading...</Match>
<Match when={commentsQuery.isError}>Error: {commentsQuery.error.message}</Match>
<Match when={commentsQuery.isSuccess}>
<ul>
<For each={commentsQuery.data.pages}>
{(page) => <For each={page.comments}>{(c) => <li>{c.text}</li>}</For>}
</For>
</ul>
</Match>
</Switch>
)
}
```

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,144 @@
---
id: mutationOptions
title: mutationOptions
redirect_from:
- framework/solid/reference/mutationOptions
---
## Call Signature
```ts
function mutationOptions<TData, TError, TVariables, TOnMutateResult>(options): WithRequired<MutationOptions<TData, TError, TVariables, TOnMutateResult>, "mutationKey">;
```
Defined in: [packages/solid-query/src/mutationOptions.ts:33](https://github.com/TanStack/query/blob/main/packages/solid-query/src/mutationOptions.ts#L33)
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)\<[`MutationOptions`](../interfaces/MutationOptions.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)\<[`MutationOptions`](../interfaces/MutationOptions.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/solid-query'
const createPostOptions = mutationOptions({
mutationKey: ['posts', 'create'],
mutationFn: createPost,
})
function SavingIndicator() {
const isCreatingPost = useMutationState(() => ({
filters: { mutationKey: createPostOptions.mutationKey, status: 'pending' },
}))
return isCreatingPost().length > 0 ? <span>Saving…</span> : null
}
```
## Call Signature
```ts
function mutationOptions<TData, TError, TVariables, TOnMutateResult>(options): Omit<MutationOptions<TData, TError, TVariables, TOnMutateResult>, "mutationKey">;
```
Defined in: [packages/solid-query/src/mutationOptions.ts:73](https://github.com/TanStack/query/blob/main/packages/solid-query/src/mutationOptions.ts#L73)
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`\<[`MutationOptions`](../interfaces/MutationOptions.md)\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>, `"mutationKey"`\>
The mutation options to use, identical to what you'd pass to `useMutation`, without a
`mutationKey`.
### Returns
`Omit`\<[`MutationOptions`](../interfaces/MutationOptions.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/solid-query'
const createPostOptions = mutationOptions({
mutationFn: createPost,
})
function CreatePost() {
const createPostMutation = useMutation(() => createPostOptions)
return <button onClick={() => createPostMutation.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,160 @@
---
id: queryOptions
title: queryOptions
redirect_from:
- framework/solid/reference/queryOptions
---
## Call Signature
```ts
function queryOptions<TQueryFnData, TError, TData, TQueryKey>(options): QueryOptions<TQueryFnData, TError, TData, TQueryKey> & object & QueryKeyWithDataTag<TQueryKey, TQueryFnData, TError>;
```
Defined in: [packages/solid-query/src/queryOptions.ts:89](https://github.com/TanStack/query/blob/main/packages/solid-query/src/queryOptions.ts#L89)
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
[`QueryOptions`](../interfaces/QueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\> & `object`
The [DefinedInitialDataOptions](../type-aliases/DefinedInitialDataOptions.md) to use — everything you can pass to `useQuery`, with `initialData` set.
### Returns
[`QueryOptions`](../interfaces/QueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\> & `object` & [`QueryKeyWithDataTag`](../type-aliases/QueryKeyWithDataTag.md)\<`TQueryKey`, `TQueryFnData`, `TError`\>
The same options object, typed so that `queryKey` carries the inferred data type.
### See
[useQuery](useQuery.md) to run a query with these options.
### Example
```tsx
import { For } from 'solid-js'
import { queryOptions, useQuery } from '@tanstack/solid-query'
const postsOptions = queryOptions({
queryKey: ['posts'],
queryFn: fetchPosts,
initialData: [],
})
function Posts() {
// `postsQuery.data` is `Post[]`, never `undefined`, thanks to `initialData` — even if a refetch fails,
// so the list stays visible alongside the error.
const postsQuery = useQuery(() => postsOptions)
return (
<div>
{postsQuery.isError ? <span>Error: {postsQuery.error.message}</span> : null}
<ul>
<For each={postsQuery.data}>{(post) => <li>{post.title}</li>}</For>
</ul>
</div>
)
}
```
## Call Signature
```ts
function queryOptions<TQueryFnData, TError, TData, TQueryKey>(options): QueryOptions<TQueryFnData, TError, TData, TQueryKey> & object & QueryKeyWithDataTag<TQueryKey, TQueryFnData, TError>;
```
Defined in: [packages/solid-query/src/queryOptions.ts:139](https://github.com/TanStack/query/blob/main/packages/solid-query/src/queryOptions.ts#L139)
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
[`QueryOptions`](../interfaces/QueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\> & `object`
The [UndefinedInitialDataOptions](../type-aliases/UndefinedInitialDataOptions.md) to use — everything you can pass to `useQuery`.
### Returns
[`QueryOptions`](../interfaces/QueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\> & `object` & [`QueryKeyWithDataTag`](../type-aliases/QueryKeyWithDataTag.md)\<`TQueryKey`, `TQueryFnData`, `TError`\>
The same options object, typed so that `queryKey` carries the inferred data type.
### See
[useQuery](useQuery.md) to run a query with these options.
### Example
A parameterized factory, so the same options object can be reused per `id`:
```tsx
import { Match, Switch } from 'solid-js'
import { queryOptions, useQuery } from '@tanstack/solid-query'
const postOptions = (id: string) =>
queryOptions({
queryKey: ['post', id],
queryFn: () => fetchPost(id),
})
function Post(props: { id: string }) {
const postQuery = useQuery(() => postOptions(props.id))
return (
<Switch>
<Match when={postQuery.isPending}>Loading...</Match>
<Match when={postQuery.isError}>Error: {postQuery.error.message}</Match>
<Match when={postQuery.isSuccess}>
<h1>{postQuery.data.title}</h1>
</Match>
</Switch>
)
}
```

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,259 @@
---
id: useInfiniteQuery
title: useInfiniteQuery
redirect_from:
- framework/solid/reference/useInfiniteQuery
---
## Call Signature
```ts
function useInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options, queryClient?): DefinedUseInfiniteQueryResult<TData, TError>;
```
Defined in: [packages/solid-query/src/useInfiniteQuery.ts:70](https://github.com/TanStack/query/blob/main/packages/solid-query/src/useInfiniteQuery.ts#L70)
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`\>
An accessor returning the [DefinedInitialDataInfiniteOptions](../type-aliases/DefinedInitialDataInfiniteOptions.md) to use — everything you
can pass to `useInfiniteQuery`, with `initialData` set.
#### queryClient?
`Accessor`\<[`QueryClient`](../classes/QueryClient.md)\>
An accessor for 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 { For } from 'solid-js'
import { useInfiniteQuery } from '@tanstack/solid-query'
function Projects() {
// `projectsQuery.data` is never `undefined`, thanks to `initialData` — even if a refetch fails, so the
// list stays visible alongside the error.
const projectsQuery = useInfiniteQuery(() => ({
queryKey: ['projects'],
queryFn: ({ pageParam }) => fetchProjects(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
initialData: { pages: [], pageParams: [] },
}))
return (
<div>
{projectsQuery.isError ? <span>Error: {projectsQuery.error.message}</span> : null}
<ul>
<For each={projectsQuery.data.pages}>
{(page) => <For each={page.projects}>{(p) => <li>{p.name}</li>}</For>}
</For>
</ul>
</div>
)
}
```
## Call Signature
```ts
function useInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options, queryClient?): UseInfiniteQueryResult<TData, TError>;
```
Defined in: [packages/solid-query/src/useInfiniteQuery.ts:189](https://github.com/TanStack/query/blob/main/packages/solid-query/src/useInfiniteQuery.ts#L189)
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`\>
An accessor returning the [UndefinedInitialDataInfiniteOptions](../type-aliases/UndefinedInitialDataInfiniteOptions.md) to use — everything
you can pass to `useInfiniteQuery`.
#### queryClient?
`Accessor`\<[`QueryClient`](../classes/QueryClient.md)\>
An accessor for 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 { For, Match, Switch } from 'solid-js'
import { useInfiniteQuery } from '@tanstack/solid-query'
function Projects() {
const projectsQuery = useInfiniteQuery(() => ({
queryKey: ['projects'],
queryFn: ({ pageParam }) => fetchProjects(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
}))
return (
<Switch>
<Match when={projectsQuery.isPending}>Loading...</Match>
<Match when={projectsQuery.isError}>Error: {projectsQuery.error.message}</Match>
<Match when={projectsQuery.isSuccess}>
<ul>
<For each={projectsQuery.data.pages}>
{(page) => <For each={page.projects}>{(p) => <li>{p.name}</li>}</For>}
</For>
</ul>
<button
onClick={() => projectsQuery.fetchNextPage()}
disabled={!projectsQuery.hasNextPage || projectsQuery.isFetching}
>
{projectsQuery.isFetchingNextPage
? 'Loading more...'
: projectsQuery.hasNextPage
? 'Load More'
: 'Nothing more to load'}
</button>
</Match>
</Switch>
)
}
```
Fetching the next page automatically as the user scrolls, using an `IntersectionObserver` on a
sentinel element after the list:
```tsx
import { For, Match, Switch, createEffect, onCleanup } from 'solid-js'
import { useInfiniteQuery } from '@tanstack/solid-query'
function Projects() {
const projectsQuery = useInfiniteQuery(() => ({
queryKey: ['projects'],
queryFn: ({ pageParam }) => fetchProjects(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
}))
let sentinelRef: HTMLDivElement | undefined
createEffect(() => {
if (sentinelRef == null || !projectsQuery.hasNextPage || projectsQuery.isFetching) return
const observer = new IntersectionObserver(([entry]) => {
if (entry?.isIntersecting) projectsQuery.fetchNextPage()
})
observer.observe(sentinelRef)
onCleanup(() => observer.disconnect())
})
return (
<Switch>
<Match when={projectsQuery.isPending}>Loading...</Match>
<Match when={projectsQuery.isError}>Error: {projectsQuery.error.message}</Match>
<Match when={projectsQuery.isSuccess}>
<ul>
<For each={projectsQuery.data.pages}>
{(page) => <For each={page.projects}>{(p) => <li>{p.name}</li>}</For>}
</For>
</ul>
<div ref={sentinelRef}>{projectsQuery.isFetchingNextPage ? 'Loading more...' : null}</div>
</Match>
</Switch>
)
}
```

View File

@@ -0,0 +1,50 @@
---
id: useIsFetching
title: useIsFetching
redirect_from:
- framework/solid/reference/useIsFetching
---
```ts
function useIsFetching(filters?, queryClient?): Accessor<number>;
```
Defined in: [packages/solid-query/src/useIsFetching.ts:29](https://github.com/TanStack/query/blob/main/packages/solid-query/src/useIsFetching.ts#L29)
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?
`Accessor`\<[`QueryFilters`](../interfaces/QueryFilters.md)\<readonly `unknown`[]\>\>
An accessor returning the [QueryFilters](../interfaces/QueryFilters.md) to narrow down the matched queries.
### queryClient?
`Accessor`\<[`QueryClient`](../classes/QueryClient.md)\>
An accessor for a custom `QueryClient`. Otherwise, the one from the nearest context
will be used.
## Returns
`Accessor`\<`number`\>
An accessor for the `number` of the queries that your application is currently loading or fetching
in the background.
## Example
```tsx
import { useIsFetching } from '@tanstack/solid-query'
function GlobalLoadingIndicator() {
// How many queries matching the posts prefix are fetching?
const isFetchingPosts = useIsFetching(() => ({ queryKey: ['posts'] }))
return isFetchingPosts() > 0 ? <span>Loading posts...</span> : null
}
```

View File

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

View File

@@ -0,0 +1,20 @@
---
id: useIsRestoring
title: useIsRestoring
---
```ts
function useIsRestoring(): Accessor<boolean>;
```
Defined in: [packages/solid-query/src/isRestoring.ts:13](https://github.com/TanStack/query/blob/main/packages/solid-query/src/isRestoring.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
`Accessor`\<`boolean`\>
An accessor that reads `true` while a persisted client is being restored, `false` otherwise.

View File

@@ -0,0 +1,201 @@
---
id: useMutation
title: useMutation
redirect_from:
- framework/solid/reference/useMutation
---
```ts
function useMutation<TData, TError, TVariables, TOnMutateResult>(options, queryClient?): UseMutationResult<TData, TError, TVariables, TOnMutateResult>;
```
Defined in: [packages/solid-query/src/useMutation.ts:173](https://github.com/TanStack/query/blob/main/packages/solid-query/src/useMutation.ts#L173)
## Type Parameters
### TData
`TData` = `unknown`
### TError
`TError` = `Error`
### TVariables
`TVariables` = `void`
### TOnMutateResult
`TOnMutateResult` = `unknown`
## Parameters
### options
[`UseMutationOptions`](../type-aliases/UseMutationOptions.md)\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>
An accessor returning the [UseMutationOptions](../type-aliases/UseMutationOptions.md) to use.
### queryClient?
`Accessor`\<[`QueryClient`](../classes/QueryClient.md)\>
An accessor for 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.
## Examples
```tsx
import { useMutation, useQueryClient } from '@tanstack/solid-query'
function TodoItem(props: { id: number }) {
const queryClient = useQueryClient()
const deleteTodoMutation = useMutation(() => ({
mutationFn: deleteTodo,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
}))
return (
<button onClick={() => deleteTodoMutation.mutate({ id: props.id })} disabled={deleteTodoMutation.isPending}>
Delete
</button>
)
}
```
Rendering the mutation's own state, rather than just firing it off:
```tsx
import { Match, Switch } from 'solid-js'
import { useMutation, useQueryClient } from '@tanstack/solid-query'
function AddTodo() {
const queryClient = useQueryClient()
const addMutation = useMutation(() => ({
mutationFn: addTodo,
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
}))
return (
<Switch fallback={<button onClick={() => addMutation.mutate('Item')}>Add</button>}>
<Match when={addMutation.isPending}>Adding todo...</Match>
<Match when={addMutation.isError}>
<div>An error occurred: {addMutation.error?.message}</div>
<button onClick={() => addMutation.mutate('Item')}>Add</button>
</Match>
</Switch>
)
}
```
Optimistic update via `onMutate`, rolling back on `onError`:
```tsx
import { useMutation, useQueryClient } from '@tanstack/solid-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/solid-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/solid-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,109 @@
---
id: useMutationState
title: useMutationState
redirect_from:
- framework/solid/reference/useMutationState
---
```ts
function useMutationState<TResult, TMutation>(options, queryClient?): Accessor<TResult[]>;
```
Defined in: [packages/solid-query/src/useMutationState.ts:124](https://github.com/TanStack/query/blob/main/packages/solid-query/src/useMutationState.ts#L124)
`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
`Accessor`\<`MutationStateOptions`\<`TResult`, `TMutation`\>\> = `...`
An accessor returning the `filters` to narrow down matched mutations, and an optional
`select` to transform the mutation state.
### queryClient?
`Accessor`\<[`QueryClient`](../classes/QueryClient.md)\>
An accessor for a custom `QueryClient`. Otherwise, the one from the nearest context
will be used.
## Returns
`Accessor`\<`TResult`[]\>
An accessor for an array of whatever `select` returns for each matching mutation.
## Examples
Get all variables of all running mutations:
```tsx
import { useMutationState } from '@tanstack/solid-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/solid-query'
const mutationKey = ['posts']
function Posts() {
// Some mutation that we want to get the state for
const createPostsMutation = 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={() => createPostsMutation.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/solid-query'
function LatestPost() {
const savedPosts = useMutationState(() => ({
filters: { mutationKey: ['posts'], status: 'success' },
select: (mutation) => mutation.state.data,
}))
const latestPost = () => savedPosts()[savedPosts().length - 1]
return <span>{latestPost()?.title}</span>
}
```

View File

@@ -0,0 +1,156 @@
---
id: useQueries
title: useQueries
redirect_from:
- framework/solid/reference/useQueries
---
```ts
function useQueries<T, TCombinedResult>(queriesOptions, queryClient?): TCombinedResult;
```
Defined in: [packages/solid-query/src/useQueries.ts:274](https://github.com/TanStack/query/blob/main/packages/solid-query/src/useQueries.ts#L274)
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
`placeholderData` below for the one difference. 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.
`placeholderData` is supported here too, but unlike `useQuery`, it doesn't receive information from
previously rendered queries, because the number of queries can differ between renders.
## Type Parameters
### T
`T` *extends* `any`[]
### TCombinedResult
`TCombinedResult` *extends*
\| \[\]
\| \[
\| [`QueryObserverRefetchErrorResult`](../interfaces/QueryObserverRefetchErrorResult.md)\<`unknown`, `Error`\>
\| [`QueryObserverSuccessResult`](../interfaces/QueryObserverSuccessResult.md)\<`unknown`, `Error`\>
\| [`QueryObserverLoadingErrorResult`](../interfaces/QueryObserverLoadingErrorResult.md)\<`unknown`, `Error`\>
\| [`QueryObserverLoadingResult`](../interfaces/QueryObserverLoadingResult.md)\<`unknown`, `Error`\>
\| [`QueryObserverPendingResult`](../interfaces/QueryObserverPendingResult.md)\<`unknown`, `Error`\>
\| [`QueryObserverPlaceholderResult`](../interfaces/QueryObserverPlaceholderResult.md)\<`unknown`, `Error`\>
\| [`QueryObserverRefetchErrorResult`](../interfaces/QueryObserverRefetchErrorResult.md)\<`unknown`, `unknown`\>
\| [`QueryObserverSuccessResult`](../interfaces/QueryObserverSuccessResult.md)\<`unknown`, `unknown`\>
\| [`QueryObserverLoadingErrorResult`](../interfaces/QueryObserverLoadingErrorResult.md)\<`unknown`, `unknown`\>
\| [`QueryObserverLoadingResult`](../interfaces/QueryObserverLoadingResult.md)\<`unknown`, `unknown`\>
\| [`QueryObserverPendingResult`](../interfaces/QueryObserverPendingResult.md)\<`unknown`, `unknown`\>
\| [`QueryObserverPlaceholderResult`](../interfaces/QueryObserverPlaceholderResult.md)\<`unknown`, `unknown`\>\]
\| (
\| [`QueryObserverRefetchErrorResult`](../interfaces/QueryObserverRefetchErrorResult.md)\<`unknown`, `Error`\>
\| [`QueryObserverSuccessResult`](../interfaces/QueryObserverSuccessResult.md)\<`unknown`, `Error`\>
\| [`QueryObserverLoadingErrorResult`](../interfaces/QueryObserverLoadingErrorResult.md)\<`unknown`, `Error`\>
\| [`QueryObserverLoadingResult`](../interfaces/QueryObserverLoadingResult.md)\<`unknown`, `Error`\>
\| [`QueryObserverPendingResult`](../interfaces/QueryObserverPendingResult.md)\<`unknown`, `Error`\>
\| [`QueryObserverPlaceholderResult`](../interfaces/QueryObserverPlaceholderResult.md)\<`unknown`, `Error`\>
\| [`QueryObserverRefetchErrorResult`](../interfaces/QueryObserverRefetchErrorResult.md)\<`unknown`, `unknown`\>
\| [`QueryObserverSuccessResult`](../interfaces/QueryObserverSuccessResult.md)\<`unknown`, `unknown`\>
\| [`QueryObserverLoadingErrorResult`](../interfaces/QueryObserverLoadingErrorResult.md)\<`unknown`, `unknown`\>
\| [`QueryObserverLoadingResult`](../interfaces/QueryObserverLoadingResult.md)\<`unknown`, `unknown`\>
\| [`QueryObserverPendingResult`](../interfaces/QueryObserverPendingResult.md)\<`unknown`, `unknown`\>
\| [`QueryObserverPlaceholderResult`](../interfaces/QueryObserverPlaceholderResult.md)\<`unknown`, `unknown`\>)[] = `T` *extends* \[\] ? \[\] : `T` *extends* \[`Head`\] ? \[`GetResults`\<`Head`\>\] : `T` *extends* \[`Head`, `...Tail[]`\] ? \[`...Tail[]`\] *extends* \[\] ? \[\] : \[`...Tail[]`\] *extends* \[`Head`\] ? \[`GetResults`\<`Head`\>, `GetResults`\<`Head`\>\] : \[`...Tail[]`\] *extends* \[`Head`, `...Tail[]`\] ? \[`...Tail[]`\] *extends* \[\] ? \[\] : \[`...Tail[]`\] *extends* \[`Head`\] ? \[`GetResults`\<`Head`\>, `GetResults`\<`Head`\>, `GetResults`\<`Head`\>\] : \[`...Tail[]`\] *extends* \[`Head`, `...Tail[]`\] ? \[`...(...)[]`\] *extends* \[\] ? \[\] : ... *extends* ... ? ... : ... : \[`...{ [K in (...)]: (...) }[]`\] : \[...\{ \[K in string \| number \| symbol\]: GetResults\<Tail\[K\<(...)\>\]\> \}\[\]\] : \{ \[K in string \| number \| symbol\]: GetResults\<T\[K\<K\>\]\> \}
## Parameters
### queriesOptions
`Accessor`\<\{
`combine?`: (`result`) => `TCombinedResult`;
`queries`: \| readonly \[`T` *extends* \[\] ? \[\] : `T` *extends* \[`Head`\] ? \[`GetOptions`\<`Head`\>\] : `T` *extends* \[`Head`, `...Tail[]`\] ? \[`...Tail[]`\] *extends* \[\] ? \[\] : \[`...Tail[]`\] *extends* \[`Head`\] ? \[`GetOptions`\<...\>, `GetOptions`\<...\>\] : \[`...(...)[]`\] *extends* \[..., `...(...)[]`\] ? ... *extends* ... ? ... : ... : ... *extends* ... ? ... : ... : readonly `unknown`[] *extends* `T` ? `T` : `T` *extends* `UseQueryOptionsForUseQueries`\<..., ..., ..., ...\>[] ? `UseQueryOptionsForUseQueries`\<..., ..., ..., ...\>[] : `UseQueryOptionsForUseQueries`\<..., ..., ..., ...\>[]\]
\| readonly \[\{ \[K in string \| number \| symbol\]: GetOptions\<T\[K\<K\>\]\> \}\];
\}\>
An accessor returning the `queries` array to run, and an optional `combine`
function.
### queryClient?
`Accessor`\<[`QueryClient`](../classes/QueryClient.md)\>
An accessor for 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 { For } from 'solid-js'
import { useQueries } from '@tanstack/solid-query'
function Posts(props: { ids: Array<number> }) {
const postQueries = useQueries(() => ({
queries: props.ids.map((id) => ({
queryKey: ['post', id],
queryFn: () => fetchPost(id),
staleTime: Infinity,
})),
}))
return (
<ul>
<For each={postQueries}>
{(postQuery) => {
if (postQuery.isPending) return <li>Loading...</li>
if (postQuery.isError) return <li>Error: {postQuery.error.message}</li>
return <li>{postQuery.data.title}</li>
}}
</For>
</ul>
)
}
```
Combining results into a single value:
```tsx
import { For, Match, Switch } from 'solid-js'
import { useQueries } from '@tanstack/solid-query'
function Posts(props: { ids: Array<number> }) {
const combinedPostsQuery = useQueries(() => ({
queries: props.ids.map((id) => ({
queryKey: ['post', id],
queryFn: () => fetchPost(id),
})),
combine: (postQueries) => {
return {
data: postQueries.map((postQuery) => postQuery.data),
isPending: postQueries.some((postQuery) => postQuery.isPending),
isError: postQueries.some((postQuery) => postQuery.isError),
}
},
}))
return (
<Switch
fallback={
<ul>
<For each={combinedPostsQuery.data}>{(post) => <li>{post?.title}</li>}</For>
</ul>
}
>
<Match when={combinedPostsQuery.isPending}>Loading...</Match>
<Match when={combinedPostsQuery.isError}>Error loading posts</Match>
</Switch>
)
}
```

View File

@@ -0,0 +1,290 @@
---
id: useQuery
title: useQuery
redirect_from:
- framework/solid/reference/useQuery
---
## Call Signature
```ts
function useQuery<TQueryFnData, TError, TData, TQueryKey>(options, queryClient?): UseQueryResult<TData, TError>;
```
Defined in: [packages/solid-query/src/useQuery.ts:178](https://github.com/TanStack/query/blob/main/packages/solid-query/src/useQuery.ts#L178)
### 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`\>
An accessor returning the [UndefinedInitialDataOptions](../type-aliases/UndefinedInitialDataOptions.md) to use — everything you can
pass to `useQuery`.
#### queryClient?
() => [`QueryClient`](../classes/QueryClient.md)
An accessor for 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, as a Solid store. `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 { For, Match, Switch } from 'solid-js'
import { useQuery } from '@tanstack/solid-query'
function Posts() {
const postsQuery = useQuery(() => ({
queryKey: ['posts'],
queryFn: fetchPosts,
}))
return (
<Switch>
<Match when={postsQuery.isPending}>Loading...</Match>
<Match when={postsQuery.isError}>Error: {postsQuery.error.message}</Match>
<Match when={postsQuery.isSuccess}>
<ul>
<For each={postsQuery.data}>{(post) => <li>{post.title}</li>}</For>
</ul>
<div>{postsQuery.isFetching ? 'Background Updating...' : ' '}</div>
</Match>
</Switch>
)
}
```
`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 { Match, Switch } from 'solid-js'
import { useQuery } from '@tanstack/solid-query'
function PostCount() {
const postsQuery = useQuery(() => ({
queryKey: ['posts'],
queryFn: fetchPosts,
select: (posts) => posts.length,
}))
return (
<Switch>
<Match when={postsQuery.isPending}>Loading...</Match>
<Match when={postsQuery.isError}>Error: {postsQuery.error.message}</Match>
<Match when={postsQuery.isSuccess}>{postsQuery.data} posts</Match>
</Switch>
)
}
```
A dependent query, only enabled once `postId` is set:
```tsx
import { Match, Switch } from 'solid-js'
import { useQuery } from '@tanstack/solid-query'
function Post(props: { postId: number | undefined }) {
const postQuery = useQuery(() => ({
queryKey: ['post', props.postId],
queryFn: () => fetchPost(props.postId!),
enabled: props.postId != null,
}))
return (
<Switch fallback={<h1>{postQuery.data?.title}</h1>}>
<Match when={props.postId == null}>Select a post</Match>
<Match when={postQuery.isLoading}>Loading...</Match>
<Match when={postQuery.isError}>Error: {postQuery.error.message}</Match>
</Switch>
)
}
```
The same dependent query, using `skipToken` to disable it in a type-safe way instead of relying on
`enabled`. The non-null assertion is still needed — Solid's `props` narrowing doesn't survive into the
`queryFn` closure the way a local `const` would — but `skipToken` keeps `queryFn`'s return type accurate
without it. `refetch` doesn't work while `queryFn` is `skipToken` — use `enabled: false` instead if you
need to trigger the query manually:
```tsx
import { Match, Switch } from 'solid-js'
import { skipToken, useQuery } from '@tanstack/solid-query'
function Post(props: { postId: number | undefined }) {
const postQuery = useQuery(() => ({
queryKey: ['post', props.postId],
queryFn: props.postId != null ? () => fetchPost(props.postId!) : skipToken,
}))
return (
<Switch fallback={<h1>{postQuery.data?.title}</h1>}>
<Match when={props.postId == null}>Select a post</Match>
<Match when={postQuery.isLoading}>Loading...</Match>
<Match when={postQuery.isError}>Error: {postQuery.error.message}</Match>
</Switch>
)
}
```
Seeding a detail query from an already-cached list, to skip the loading state:
```tsx
import { useQuery, useQueryClient } from '@tanstack/solid-query'
function Post(props: { postId: number }) {
const queryClient = useQueryClient()
const postQuery = useQuery(() => ({
queryKey: ['post', props.postId],
queryFn: () => fetchPost(props.postId),
initialData: () =>
queryClient
.getQueryData<Array<Post>>(['posts'])
?.find((post) => post.id === props.postId),
}))
return postQuery.isError ? <span>Error: {postQuery.error.message}</span> : <h1>{postQuery.data?.title}</h1>
}
```
Paginated data, keeping the previous page's data visible while the next page loads:
```tsx
import { For, createSignal } from 'solid-js'
import { keepPreviousData, useQuery } from '@tanstack/solid-query'
function Posts() {
const [page, setPage] = createSignal(0)
const postsQuery = useQuery(() => ({
queryKey: ['posts', page()],
queryFn: () => fetchPosts(page()),
placeholderData: keepPreviousData,
}))
return (
<div>
<ul>
<For each={postsQuery.data}>{(post) => <li>{post.title}</li>}</For>
</ul>
<button
disabled={postsQuery.isPlaceholderData}
onClick={() => setPage((old) => old + 1)}
>
Next Page
</button>
</div>
)
}
```
## Call Signature
```ts
function useQuery<TQueryFnData, TError, TData, TQueryKey>(options, queryClient?): DefinedUseQueryResult<TData, TError>;
```
Defined in: [packages/solid-query/src/useQuery.ts:226](https://github.com/TanStack/query/blob/main/packages/solid-query/src/useQuery.ts#L226)
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`\>
An accessor returning the [DefinedInitialDataOptions](../type-aliases/DefinedInitialDataOptions.md) to use — everything you can
pass to `useQuery`, with `initialData` set.
#### queryClient?
() => [`QueryClient`](../classes/QueryClient.md)
An accessor for 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, as a Solid store, 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 { For } from 'solid-js'
import { useQuery } from '@tanstack/solid-query'
function Posts() {
// `postsQuery.data` is never `undefined`, thanks to `initialData` — even if a refetch fails, so the
// list stays visible alongside the error.
const postsQuery = useQuery(() => ({
queryKey: ['posts'],
queryFn: fetchPosts,
initialData: [],
}))
return (
<div>
{postsQuery.isError ? <span>Error: {postsQuery.error.message}</span> : null}
<ul>
<For each={postsQuery.data}>{(post) => <li>{post.title}</li>}</For>
</ul>
</div>
)
}
```

View File

@@ -0,0 +1,31 @@
---
id: useQueryClient
title: useQueryClient
---
```ts
function useQueryClient(queryClient?): QueryClient;
```
Defined in: [packages/solid-query/src/QueryClientProvider.tsx:28](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClientProvider.tsx#L28)
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.