diff --git a/docs/config.json b/docs/config.json index c9a0c6cf45..a8172251fa 100644 --- a/docs/config.json +++ b/docs/config.json @@ -1343,48 +1343,192 @@ "label": "solid", "children": [ { - "label": "useQuery", - "to": "framework/solid/reference/useQuery" + "label": "Solid Reference", + "to": "framework/solid/reference/index" }, { - "label": "useQueries", - "to": "framework/solid/reference/useQueries" + "label": "Functions / useQuery", + "to": "framework/solid/reference/functions/useQuery" }, { - "label": "useInfiniteQuery", - "to": "framework/solid/reference/useInfiniteQuery" + "label": "Functions / queryOptions", + "to": "framework/solid/reference/functions/queryOptions" }, { - "label": "useMutation", - "to": "framework/solid/reference/useMutation" + "label": "Functions / QueryClientProvider", + "to": "framework/solid/reference/functions/QueryClientProvider" }, { - "label": "useIsFetching", - "to": "framework/solid/reference/useIsFetching" + "label": "Functions / useQueryClient", + "to": "framework/solid/reference/functions/useQueryClient" }, { - "label": "useIsMutating", - "to": "framework/solid/reference/useIsMutating" + "label": "Functions / useIsFetching", + "to": "framework/solid/reference/functions/useIsFetching" }, { - "label": "useMutationState", - "to": "framework/solid/reference/useMutationState" + "label": "Functions / useInfiniteQuery", + "to": "framework/solid/reference/functions/useInfiniteQuery" }, { - "label": "queryOptions", - "to": "framework/solid/reference/queryOptions" + "label": "Functions / infiniteQueryOptions", + "to": "framework/solid/reference/functions/infiniteQueryOptions" }, { - "label": "infiniteQueryOptions", - "to": "framework/solid/reference/infiniteQueryOptions" + "label": "Functions / useMutation", + "to": "framework/solid/reference/functions/useMutation" }, { - "label": "mutationOptions", - "to": "framework/solid/reference/mutationOptions" + "label": "Functions / mutationOptions", + "to": "framework/solid/reference/functions/mutationOptions" }, { - "label": "hydration", - "to": "framework/solid/reference/hydration" + "label": "Functions / useIsMutating", + "to": "framework/solid/reference/functions/useIsMutating" + }, + { + "label": "Functions / useMutationState", + "to": "framework/solid/reference/functions/useMutationState" + }, + { + "label": "Functions / useQueries", + "to": "framework/solid/reference/functions/useQueries" + }, + { + "label": "Functions / useIsRestoring", + "to": "framework/solid/reference/functions/useIsRestoring" + }, + { + "label": "Classes / QueryClient", + "to": "framework/solid/reference/classes/QueryClient" + }, + { + "label": "Interfaces / DefaultOptions", + "to": "framework/solid/reference/interfaces/DefaultOptions" + }, + { + "label": "Interfaces / InfiniteQueryObserverOptions", + "to": "framework/solid/reference/interfaces/InfiniteQueryObserverOptions" + }, + { + "label": "Interfaces / InfiniteQueryOptions", + "to": "framework/solid/reference/interfaces/InfiniteQueryOptions" + }, + { + "label": "Interfaces / MutationOptions", + "to": "framework/solid/reference/interfaces/MutationOptions" + }, + { + "label": "Interfaces / QueryClientConfig", + "to": "framework/solid/reference/interfaces/QueryClientConfig" + }, + { + "label": "Interfaces / QueryObserverOptions", + "to": "framework/solid/reference/interfaces/QueryObserverOptions" + }, + { + "label": "Interfaces / QueryOptions", + "to": "framework/solid/reference/interfaces/QueryOptions" + }, + { + "label": "Interfaces / UseBaseQueryOptions", + "to": "framework/solid/reference/interfaces/UseBaseQueryOptions" + }, + { + "label": "Types / DefinedInitialDataInfiniteOptions", + "to": "framework/solid/reference/type-aliases/DefinedInitialDataInfiniteOptions" + }, + { + "label": "Types / DefinedInitialDataOptions", + "to": "framework/solid/reference/type-aliases/DefinedInitialDataOptions" + }, + { + "label": "Types / DefinedUseBaseQueryResult", + "to": "framework/solid/reference/type-aliases/DefinedUseBaseQueryResult" + }, + { + "label": "Types / DefinedUseInfiniteQueryResult", + "to": "framework/solid/reference/type-aliases/DefinedUseInfiniteQueryResult" + }, + { + "label": "Types / DefinedUseQueryResult", + "to": "framework/solid/reference/type-aliases/DefinedUseQueryResult" + }, + { + "label": "Types / QueryClientProviderProps", + "to": "framework/solid/reference/type-aliases/QueryClientProviderProps" + }, + { + "label": "Types / UndefinedInitialDataInfiniteOptions", + "to": "framework/solid/reference/type-aliases/UndefinedInitialDataInfiniteOptions" + }, + { + "label": "Types / UndefinedInitialDataOptions", + "to": "framework/solid/reference/type-aliases/UndefinedInitialDataOptions" + }, + { + "label": "Types / UseBaseMutationResult", + "to": "framework/solid/reference/type-aliases/UseBaseMutationResult" + }, + { + "label": "Types / UseBaseQueryResult", + "to": "framework/solid/reference/type-aliases/UseBaseQueryResult" + }, + { + "label": "Types / UseInfiniteQueryOptions", + "to": "framework/solid/reference/type-aliases/UseInfiniteQueryOptions" + }, + { + "label": "Types / UseInfiniteQueryResult", + "to": "framework/solid/reference/type-aliases/UseInfiniteQueryResult" + }, + { + "label": "Types / UseMutateAsyncFunction", + "to": "framework/solid/reference/type-aliases/UseMutateAsyncFunction" + }, + { + "label": "Types / UseMutateFunction", + "to": "framework/solid/reference/type-aliases/UseMutateFunction" + }, + { + "label": "Types / UseMutationOptions", + "to": "framework/solid/reference/type-aliases/UseMutationOptions" + }, + { + "label": "Types / UseMutationResult", + "to": "framework/solid/reference/type-aliases/UseMutationResult" + }, + { + "label": "Types / UseQueryOptions", + "to": "framework/solid/reference/type-aliases/UseQueryOptions" + }, + { + "label": "Types / UseQueryResult", + "to": "framework/solid/reference/type-aliases/UseQueryResult" + }, + { + "label": "Variables / IsRestoringProvider", + "to": "framework/solid/reference/variables/IsRestoringProvider" + }, + { + "label": "Variables / QueryClientContext", + "to": "framework/solid/reference/variables/QueryClientContext" + }, + { + "label": "Variables / createInfiniteQuery", + "to": "framework/solid/reference/variables/createInfiniteQuery" + }, + { + "label": "Variables / createMutation", + "to": "framework/solid/reference/variables/createMutation" + }, + { + "label": "Variables / createQueries", + "to": "framework/solid/reference/variables/createQueries" + }, + { + "label": "Variables / createQuery", + "to": "framework/solid/reference/variables/createQuery" } ] }, diff --git a/docs/framework/solid/reference/classes/QueryClient.md b/docs/framework/solid/reference/classes/QueryClient.md new file mode 100644 index 0000000000..b46ac5ef93 --- /dev/null +++ b/docs/framework/solid/reference/classes/QueryClient.md @@ -0,0 +1,39 @@ +--- +id: QueryClient +title: QueryClient +--- + +Defined in: [QueryClient.ts:113](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClient.ts#L113) + +The core `@tanstack/query-core` `QueryClient`, typed so its `defaultOptions.queries` accepts Solid's +`reconcile` option. + +## Extends + +- `QueryClient` + +## Constructors + +### Constructor + +```ts +new QueryClient(config): QueryClient; +``` + +Defined in: [QueryClient.ts:114](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClient.ts#L114) + +#### Parameters + +##### config + +[`QueryClientConfig`](../interfaces/QueryClientConfig.md) = `{}` + +#### Returns + +`QueryClient` + +#### Overrides + +```ts +QueryCoreClient.constructor +``` diff --git a/docs/framework/solid/reference/functions/QueryClientProvider.md b/docs/framework/solid/reference/functions/QueryClientProvider.md new file mode 100644 index 0000000000..d0262e5304 --- /dev/null +++ b/docs/framework/solid/reference/functions/QueryClientProvider.md @@ -0,0 +1,39 @@ +--- +id: QueryClientProvider +title: QueryClientProvider +--- + +```ts +function QueryClientProvider(props): Element; +``` + +Defined in: [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 ... +} +``` diff --git a/docs/framework/solid/reference/functions/infiniteQueryOptions.md b/docs/framework/solid/reference/functions/infiniteQueryOptions.md new file mode 100644 index 0000000000..7ed616c850 --- /dev/null +++ b/docs/framework/solid/reference/functions/infiniteQueryOptions.md @@ -0,0 +1,176 @@ +--- +id: infiniteQueryOptions +title: infiniteQueryOptions +--- + +## Call Signature + +```ts +function infiniteQueryOptions(options): InfiniteQueryOptions & object & QueryKeyWithDataTag, TError>; +``` + +Defined in: [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`\<`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`\<`TQueryKey`, `InfiniteData`\<`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 ( +
+ {projectsQuery.isError ? Error: {projectsQuery.error.message} : null} +
    + + {(page) => {(p) =>
  • {p.name}
  • }
    } +
    +
+
+ ) +} +``` + +## Call Signature + +```ts +function infiniteQueryOptions(options): InfiniteQueryOptions & object & QueryKeyWithDataTag, TError>; +``` + +Defined in: [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`\<`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`\<`TQueryKey`, `InfiniteData`\<`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 ( + + Loading... + Error: {commentsQuery.error.message} + +
    + + {(page) => {(c) =>
  • {c.text}
  • }
    } +
    +
+
+
+ ) +} +``` diff --git a/docs/framework/solid/reference/functions/mutationOptions.md b/docs/framework/solid/reference/functions/mutationOptions.md new file mode 100644 index 0000000000..ceca140b48 --- /dev/null +++ b/docs/framework/solid/reference/functions/mutationOptions.md @@ -0,0 +1,142 @@ +--- +id: mutationOptions +title: mutationOptions +--- + +## Call Signature + +```ts +function mutationOptions(options): WithRequired, "mutationKey">; +``` + +Defined in: [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`\<[`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`\<[`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 ? Saving… : null +} +``` + +## Call Signature + +```ts +function mutationOptions(options): Omit, "mutationKey">; +``` + +Defined in: [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 +} +``` diff --git a/docs/framework/solid/reference/functions/queryOptions.md b/docs/framework/solid/reference/functions/queryOptions.md new file mode 100644 index 0000000000..771c5611fa --- /dev/null +++ b/docs/framework/solid/reference/functions/queryOptions.md @@ -0,0 +1,160 @@ +--- +id: queryOptions +title: queryOptions +--- + +## Call Signature + +```ts +function queryOptions(options): QueryOptions & object & QueryKeyWithDataTag; +``` + +Defined in: [queryOptions.ts:90](https://github.com/TanStack/query/blob/main/packages/solid-query/src/queryOptions.ts#L90) + +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`\<`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. + - [The Query Options API](https://tkdodo.eu/blog/the-query-options-api) for more on this pattern. + +### 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 ( +
+ {postsQuery.isError ? Error: {postsQuery.error.message} : null} +
    + {(post) =>
  • {post.title}
  • }
    +
+
+ ) +} +``` + +## Call Signature + +```ts +function queryOptions(options): QueryOptions & object & QueryKeyWithDataTag; +``` + +Defined in: [queryOptions.ts:141](https://github.com/TanStack/query/blob/main/packages/solid-query/src/queryOptions.ts#L141) + +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`\<`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. + - [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 { 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 ( + + Loading... + Error: {postQuery.error.message} + +

{postQuery.data.title}

+
+
+ ) +} +``` diff --git a/docs/framework/solid/reference/functions/useInfiniteQuery.md b/docs/framework/solid/reference/functions/useInfiniteQuery.md new file mode 100644 index 0000000000..4da08782e5 --- /dev/null +++ b/docs/framework/solid/reference/functions/useInfiniteQuery.md @@ -0,0 +1,257 @@ +--- +id: useInfiniteQuery +title: useInfiniteQuery +--- + +## Call Signature + +```ts +function useInfiniteQuery(options, queryClient?): DefinedUseInfiniteQueryResult; +``` + +Defined in: [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`\<`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` 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 ( +
+ {projectsQuery.isError ? Error: {projectsQuery.error.message} : null} +
    + + {(page) => {(p) =>
  • {p.name}
  • }
    } +
    +
+
+ ) +} +``` + +## Call Signature + +```ts +function useInfiniteQuery(options, queryClient?): UseInfiniteQueryResult; +``` + +Defined in: [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`\<`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` 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 ( + + Loading... + Error: {projectsQuery.error.message} + +
    + + {(page) => {(p) =>
  • {p.name}
  • }
    } +
    +
+ +
+
+ ) +} +``` + +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 ( + + Loading... + Error: {projectsQuery.error.message} + +
    + + {(page) => {(p) =>
  • {p.name}
  • }
    } +
    +
+
{projectsQuery.isFetchingNextPage ? 'Loading more...' : null}
+
+
+ ) +} +``` diff --git a/docs/framework/solid/reference/functions/useIsFetching.md b/docs/framework/solid/reference/functions/useIsFetching.md new file mode 100644 index 0000000000..085cfc3ce4 --- /dev/null +++ b/docs/framework/solid/reference/functions/useIsFetching.md @@ -0,0 +1,48 @@ +--- +id: useIsFetching +title: useIsFetching +--- + +```ts +function useIsFetching(filters?, queryClient?): Accessor; +``` + +Defined in: [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`\\> + +An accessor returning the QueryFilters 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 ? Loading posts... : null +} +``` diff --git a/docs/framework/solid/reference/functions/useIsMutating.md b/docs/framework/solid/reference/functions/useIsMutating.md new file mode 100644 index 0000000000..1ba776ec8b --- /dev/null +++ b/docs/framework/solid/reference/functions/useIsMutating.md @@ -0,0 +1,47 @@ +--- +id: useIsMutating +title: useIsMutating +--- + +```ts +function useIsMutating(filters?, queryClient?): Accessor; +``` + +Defined in: [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`\<`unknown`, `Error`, `unknown`, `unknown`\>\> + +An accessor returning the MutationFilters 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 ? Saving posts... : null +} +``` diff --git a/docs/framework/solid/reference/functions/useIsRestoring.md b/docs/framework/solid/reference/functions/useIsRestoring.md new file mode 100644 index 0000000000..ee789d94aa --- /dev/null +++ b/docs/framework/solid/reference/functions/useIsRestoring.md @@ -0,0 +1,20 @@ +--- +id: useIsRestoring +title: useIsRestoring +--- + +```ts +function useIsRestoring(): Accessor; +``` + +Defined in: [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. diff --git a/docs/framework/solid/reference/functions/useMutation.md b/docs/framework/solid/reference/functions/useMutation.md new file mode 100644 index 0000000000..76d50b6795 --- /dev/null +++ b/docs/framework/solid/reference/functions/useMutation.md @@ -0,0 +1,76 @@ +--- +id: useMutation +title: useMutation +--- + +```ts +function useMutation(options, queryClient?): UseMutationResult; +``` + +Defined in: [useMutation.ts:46](https://github.com/TanStack/query/blob/main/packages/solid-query/src/useMutation.ts#L46) + +## 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. + +## Example + +```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 ( + + ) +} +``` diff --git a/docs/framework/solid/reference/functions/useMutationState.md b/docs/framework/solid/reference/functions/useMutationState.md new file mode 100644 index 0000000000..6db1c0bb6a --- /dev/null +++ b/docs/framework/solid/reference/functions/useMutationState.md @@ -0,0 +1,107 @@ +--- +id: useMutationState +title: useMutationState +--- + +```ts +function useMutationState(options, queryClient?): Accessor; +``` + +Defined in: [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) to narrow down your mutations, and `select` to transform the mutation +state. + +## Type Parameters + +### TResult + +`TResult` = `MutationState`\<`unknown`, `Error`, `unknown`, `unknown`\> + +### TMutation + +`TMutation` *extends* `Mutation`\<`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 ( + + ) +} +``` + +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 {latestPost()?.title} +} +``` diff --git a/docs/framework/solid/reference/functions/useQueries.md b/docs/framework/solid/reference/functions/useQueries.md new file mode 100644 index 0000000000..1b9fb33537 --- /dev/null +++ b/docs/framework/solid/reference/functions/useQueries.md @@ -0,0 +1,153 @@ +--- +id: useQueries +title: useQueries +--- + +```ts +function useQueries(queriesOptions, queryClient?): TCombinedResult; +``` + +Defined in: [useQueries.ts:273](https://github.com/TanStack/query/blob/main/packages/solid-query/src/useQueries.ts#L273) + +The `useQueries` hook can be used to fetch a variable number of queries. + +The `queries` key accepts an array with query option objects identical to `useQuery`. 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`\<`unknown`, `Error`\> + \| `QueryObserverSuccessResult`\<`unknown`, `Error`\> + \| `QueryObserverLoadingErrorResult`\<`unknown`, `Error`\> + \| `QueryObserverLoadingResult`\<`unknown`, `Error`\> + \| `QueryObserverPendingResult`\<`unknown`, `Error`\> + \| `QueryObserverPlaceholderResult`\<`unknown`, `Error`\> + \| `QueryObserverRefetchErrorResult`\<`unknown`, `unknown`\> + \| `QueryObserverSuccessResult`\<`unknown`, `unknown`\> + \| `QueryObserverLoadingErrorResult`\<`unknown`, `unknown`\> + \| `QueryObserverLoadingResult`\<`unknown`, `unknown`\> + \| `QueryObserverPendingResult`\<`unknown`, `unknown`\> + \| `QueryObserverPlaceholderResult`\<`unknown`, `unknown`\>\] + \| ( + \| `QueryObserverRefetchErrorResult`\<`unknown`, `Error`\> + \| `QueryObserverSuccessResult`\<`unknown`, `Error`\> + \| `QueryObserverLoadingErrorResult`\<`unknown`, `Error`\> + \| `QueryObserverLoadingResult`\<`unknown`, `Error`\> + \| `QueryObserverPendingResult`\<`unknown`, `Error`\> + \| `QueryObserverPlaceholderResult`\<`unknown`, `Error`\> + \| `QueryObserverRefetchErrorResult`\<`unknown`, `unknown`\> + \| `QueryObserverSuccessResult`\<`unknown`, `unknown`\> + \| `QueryObserverLoadingErrorResult`\<`unknown`, `unknown`\> + \| `QueryObserverLoadingResult`\<`unknown`, `unknown`\> + \| `QueryObserverPendingResult`\<`unknown`, `unknown`\> + \| `QueryObserverPlaceholderResult`\<`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\\]\> \}\[\]\] : \{ \[K in string \| number \| symbol\]: GetResults\\]\> \} + +## 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\\]\> \}\]; +\}\> + +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 }) { + const postQueries = useQueries(() => ({ + queries: props.ids.map((id) => ({ + queryKey: ['post', id], + queryFn: () => fetchPost(id), + staleTime: Infinity, + })), + })) + + return ( +
    + + {(postQuery) => { + if (postQuery.isPending) return
  • Loading...
  • + if (postQuery.isError) return
  • Error: {postQuery.error.message}
  • + return
  • {postQuery.data.title}
  • + }} +
    +
+ ) +} +``` + +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 }) { + 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 ( + + {(post) =>
  • {post?.title}
  • }
    + + } + > + Loading... + Error loading posts +
    + ) +} +``` diff --git a/docs/framework/solid/reference/functions/useQuery.md b/docs/framework/solid/reference/functions/useQuery.md new file mode 100644 index 0000000000..f9fa5b7a9c --- /dev/null +++ b/docs/framework/solid/reference/functions/useQuery.md @@ -0,0 +1,288 @@ +--- +id: useQuery +title: useQuery +--- + +## Call Signature + +```ts +function useQuery(options, queryClient?): UseQueryResult; +``` + +Defined in: [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 ( + + Loading... + Error: {postsQuery.error.message} + +
      + {(post) =>
    • {post.title}
    • }
      +
    +
    {postsQuery.isFetching ? 'Background Updating...' : ' '}
    +
    +
    + ) +} +``` + +`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 ( + + Loading... + Error: {postsQuery.error.message} + {postsQuery.data} posts + + ) +} +``` + +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 ( + {postQuery.data?.title}}> + Select a post + Loading... + Error: {postQuery.error.message} + + ) +} +``` + +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 ( + {postQuery.data?.title}}> + Select a post + Loading... + Error: {postQuery.error.message} + + ) +} +``` + +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>(['posts']) + ?.find((post) => post.id === props.postId), + })) + + return postQuery.isError ? Error: {postQuery.error.message} :

    {postQuery.data?.title}

    +} +``` + +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 ( +
    +
      + {(post) =>
    • {post.title}
    • }
      +
    + +
    + ) +} +``` + +## Call Signature + +```ts +function useQuery(options, queryClient?): DefinedUseQueryResult; +``` + +Defined in: [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 ( +
    + {postsQuery.isError ? Error: {postsQuery.error.message} : null} +
      + {(post) =>
    • {post.title}
    • }
      +
    +
    + ) +} +``` diff --git a/docs/framework/solid/reference/functions/useQueryClient.md b/docs/framework/solid/reference/functions/useQueryClient.md new file mode 100644 index 0000000000..08f58f974b --- /dev/null +++ b/docs/framework/solid/reference/functions/useQueryClient.md @@ -0,0 +1,31 @@ +--- +id: useQueryClient +title: useQueryClient +--- + +```ts +function useQueryClient(queryClient?): QueryClient; +``` + +Defined in: [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. diff --git a/docs/framework/solid/reference/hydration.md b/docs/framework/solid/reference/hydration.md deleted file mode 100644 index f2007dea7e..0000000000 --- a/docs/framework/solid/reference/hydration.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: hydration -title: hydration ---- - -## `dehydrate` - -`dehydrate` creates a frozen representation of a `cache` that can later be hydrated with `hydrate`. This is useful for passing prefetched queries from server to client or persisting queries to localStorage or other persistent locations. It only includes currently successful queries by default. - -```ts -import { dehydrate } from '@tanstack/solid-query' - -const dehydratedState = dehydrate(queryClient, { - shouldDehydrateQuery, - shouldDehydrateMutation, -}) -``` - -**Options** - -- `client: QueryClient` - - **Required** - - The `queryClient` that should be dehydrated -- `options: DehydrateOptions` - - Optional - - `shouldDehydrateMutation: (mutation: Mutation) => boolean` - - Optional - - Whether to dehydrate mutations. - - The function is called for each mutation in the cache - - Return `true` to include this mutation in dehydration, or `false` otherwise - - Defaults to only including paused mutations - - If you would like to extend the function while retaining the default behavior, import and execute `defaultShouldDehydrateMutation` as part of the return statement - - `shouldDehydrateQuery: (query: Query) => boolean` - - Optional - - Whether to dehydrate queries. - - The function is called for each query in the cache - - Return `true` to include this query in dehydration, or `false` otherwise - - Defaults to only including successful queries - - If you would like to extend the function while retaining the default behavior, import and execute `defaultShouldDehydrateQuery` as part of the return statement - - `serializeData?: (data: any) => any` A function to transform (serialize) data during dehydration. - - `shouldRedactErrors?: (error: unknown) => boolean` - - Optional - - Only applies to queries that are still `pending` at dehydration time — their promise is dehydrated too, and this function decides whether to redact the error if that promise later rejects. - - The function is called with that rejection error - - Return `true` to redact it, or `false` otherwise - - Defaults to redacting all such errors - - Does **not** apply to `query.state.error` on already-settled queries — that error is included in the dehydrated state as-is, so sanitize it yourself via `shouldDehydrateQuery` if it may contain sensitive data - -**Returns** - -- `dehydratedState: DehydratedState` - - This includes everything that is needed to hydrate the `queryClient` at a later point - - You **should not** rely on the exact format of this response, it is not part of the public API and can change at any time - - This result is not in serialized form, you need to do that yourself if desired - -### Limitations - -Some storage systems (such as browser [Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API)) require values to be JSON serializable. If you need to dehydrate values that are not automatically serializable to JSON (like `Error` or `undefined`), you have to serialize them for yourself. Since only successful queries are included per default, to also include `Errors`, you have to provide `shouldDehydrateQuery`, e.g.: - -```ts -// server -const state = dehydrate(client, { shouldDehydrateQuery: () => true }) // to also include Errors -const serializedState = mySerialize(state) // transform Error instances to objects - -// client -const state = myDeserialize(serializedState) // transform objects back to Error instances -hydrate(client, state) -``` - -## `hydrate` - -`hydrate` adds a previously dehydrated state into a `cache`. - -```ts -import { hydrate } from '@tanstack/solid-query' - -hydrate(queryClient, dehydratedState, options) -``` - -**Options** - -- `client: QueryClient` - - **Required** - - The `queryClient` to hydrate the state into -- `dehydratedState: DehydratedState` - - **Required** - - The state to hydrate into the client -- `options: HydrateOptions` - - Optional - - `defaultOptions: DefaultOptions` - - Optional - - `mutations: MutationOptions` The default mutation options to use for the hydrated mutations. - - `queries: QueryOptions` The default query options to use for the hydrated queries. - - `deserializeData?: (data: any) => any` A function to transform (deserialize) data before it is put into the cache. - -### Limitations - -If the queries you're trying to hydrate already exist in the queryCache, `hydrate` will only overwrite them if the data is newer than the data present in the cache. Otherwise, it will **not** get applied. diff --git a/docs/framework/solid/reference/index.md b/docs/framework/solid/reference/index.md new file mode 100644 index 0000000000..72ac491bd8 --- /dev/null +++ b/docs/framework/solid/reference/index.md @@ -0,0 +1,167 @@ +--- +id: "@tanstack/solid-query" +title: "@tanstack/solid-query" +--- + +## Classes + +- [QueryClient](classes/QueryClient.md) + +## Interfaces + +- [DefaultOptions](interfaces/DefaultOptions.md) +- [InfiniteQueryObserverOptions](interfaces/InfiniteQueryObserverOptions.md) +- [InfiniteQueryOptions](interfaces/InfiniteQueryOptions.md) +- [MutationOptions](interfaces/MutationOptions.md) +- [QueryClientConfig](interfaces/QueryClientConfig.md) +- [QueryObserverOptions](interfaces/QueryObserverOptions.md) +- [QueryOptions](interfaces/QueryOptions.md) +- [UseBaseQueryOptions](interfaces/UseBaseQueryOptions.md) + +## Type Aliases + +- [DefinedInitialDataInfiniteOptions](type-aliases/DefinedInitialDataInfiniteOptions.md) +- [DefinedInitialDataOptions](type-aliases/DefinedInitialDataOptions.md) +- [DefinedUseBaseQueryResult](type-aliases/DefinedUseBaseQueryResult.md) +- [DefinedUseInfiniteQueryResult](type-aliases/DefinedUseInfiniteQueryResult.md) +- [DefinedUseQueryResult](type-aliases/DefinedUseQueryResult.md) +- [QueryClientProviderProps](type-aliases/QueryClientProviderProps.md) +- [UndefinedInitialDataInfiniteOptions](type-aliases/UndefinedInitialDataInfiniteOptions.md) +- [UndefinedInitialDataOptions](type-aliases/UndefinedInitialDataOptions.md) +- [UseBaseMutationResult](type-aliases/UseBaseMutationResult.md) +- [UseBaseQueryResult](type-aliases/UseBaseQueryResult.md) +- [UseInfiniteQueryOptions](type-aliases/UseInfiniteQueryOptions.md) +- [UseInfiniteQueryResult](type-aliases/UseInfiniteQueryResult.md) +- [UseMutateAsyncFunction](type-aliases/UseMutateAsyncFunction.md) +- [UseMutateFunction](type-aliases/UseMutateFunction.md) +- [UseMutationOptions](type-aliases/UseMutationOptions.md) +- [UseMutationResult](type-aliases/UseMutationResult.md) +- [UseQueryOptions](type-aliases/UseQueryOptions.md) +- [UseQueryResult](type-aliases/UseQueryResult.md) + +## Variables + +- [createInfiniteQuery](variables/createInfiniteQuery.md) +- [createMutation](variables/createMutation.md) +- [createQueries](variables/createQueries.md) +- [createQuery](variables/createQuery.md) +- [IsRestoringProvider](variables/IsRestoringProvider.md) +- [QueryClientContext](variables/QueryClientContext.md) + +## Functions + +- [infiniteQueryOptions](functions/infiniteQueryOptions.md) +- [mutationOptions](functions/mutationOptions.md) +- [QueryClientProvider](functions/QueryClientProvider.md) +- [queryOptions](functions/queryOptions.md) +- [useInfiniteQuery](functions/useInfiniteQuery.md) +- [useIsFetching](functions/useIsFetching.md) +- [useIsMutating](functions/useIsMutating.md) +- [useIsRestoring](functions/useIsRestoring.md) +- [useMutation](functions/useMutation.md) +- [useMutationState](functions/useMutationState.md) +- [useQueries](functions/useQueries.md) +- [useQuery](functions/useQuery.md) +- [useQueryClient](functions/useQueryClient.md) + +## References + +### CreateBaseMutationResult + +Renames and re-exports [UseBaseMutationResult](type-aliases/UseBaseMutationResult.md) + +*** + +### CreateBaseQueryOptions + +Renames and re-exports [UseBaseQueryOptions](interfaces/UseBaseQueryOptions.md) + +*** + +### CreateBaseQueryResult + +Renames and re-exports [UseBaseQueryResult](type-aliases/UseBaseQueryResult.md) + +*** + +### CreateInfiniteQueryOptions + +Renames and re-exports [UseInfiniteQueryOptions](type-aliases/UseInfiniteQueryOptions.md) + +*** + +### CreateInfiniteQueryResult + +Renames and re-exports [UseInfiniteQueryResult](type-aliases/UseInfiniteQueryResult.md) + +*** + +### createIsFetching + +Renames and re-exports [useIsFetching](functions/useIsFetching.md) + +*** + +### createIsMutating + +Renames and re-exports [useIsMutating](functions/useIsMutating.md) + +*** + +### CreateMutateAsyncFunction + +Renames and re-exports [UseMutateAsyncFunction](type-aliases/UseMutateAsyncFunction.md) + +*** + +### CreateMutateFunction + +Renames and re-exports [UseMutateFunction](type-aliases/UseMutateFunction.md) + +*** + +### CreateMutationOptions + +Renames and re-exports [UseMutationOptions](type-aliases/UseMutationOptions.md) + +*** + +### CreateMutationResult + +Renames and re-exports [UseMutationResult](type-aliases/UseMutationResult.md) + +*** + +### createMutationState + +Renames and re-exports [useMutationState](functions/useMutationState.md) + +*** + +### CreateQueryOptions + +Renames and re-exports [UseQueryOptions](type-aliases/UseQueryOptions.md) + +*** + +### CreateQueryResult + +Renames and re-exports [UseQueryResult](type-aliases/UseQueryResult.md) + +*** + +### DefinedCreateBaseQueryResult + +Renames and re-exports [DefinedUseBaseQueryResult](type-aliases/DefinedUseBaseQueryResult.md) + +*** + +### DefinedCreateInfiniteQueryResult + +Renames and re-exports [DefinedUseInfiniteQueryResult](type-aliases/DefinedUseInfiniteQueryResult.md) + +*** + +### DefinedCreateQueryResult + +Renames and re-exports [DefinedUseQueryResult](type-aliases/DefinedUseQueryResult.md) diff --git a/docs/framework/solid/reference/infiniteQueryOptions.md b/docs/framework/solid/reference/infiniteQueryOptions.md deleted file mode 100644 index 5455c2a440..0000000000 --- a/docs/framework/solid/reference/infiniteQueryOptions.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -id: infiniteQueryOptions -title: infiniteQueryOptions ---- - -```tsx -infiniteQueryOptions({ - queryKey, - ...options, -}) -``` - -**Options** - -You can generally pass everything to `infiniteQueryOptions` that you can also pass to [`useInfiniteQuery`](./useInfiniteQuery.md). These options can be shared across hooks and imperative APIs such as `queryClient.infiniteQuery`. - -- `queryKey: QueryKey` - - **Required** - - The query key to generate options for. - -See [useInfiniteQuery](./useInfiniteQuery.md) for more information. diff --git a/docs/framework/solid/reference/interfaces/DefaultOptions.md b/docs/framework/solid/reference/interfaces/DefaultOptions.md new file mode 100644 index 0000000000..50e7ba42e2 --- /dev/null +++ b/docs/framework/solid/reference/interfaces/DefaultOptions.md @@ -0,0 +1,37 @@ +--- +id: DefaultOptions +title: DefaultOptions +--- + +Defined in: [QueryClient.ts:96](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClient.ts#L96) + +The default options a `QueryClient` applies to every query, with Solid's `reconcile` option added to +`queries`. + +## Extends + +- `DefaultOptions`\<`TError`\> + +## Type Parameters + +### TError + +`TError` = `DefaultError` + +The default type of errors thrown by queries and mutations using this `QueryClient`. + +## Properties + +### queries? + +```ts +optional queries: OmitKeyof, "queryKey">; +``` + +Defined in: [QueryClient.ts:99](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClient.ts#L99) + +#### Overrides + +```ts +CoreDefaultOptions.queries +``` diff --git a/docs/framework/solid/reference/interfaces/InfiniteQueryObserverOptions.md b/docs/framework/solid/reference/interfaces/InfiniteQueryObserverOptions.md new file mode 100644 index 0000000000..dfd2f69f41 --- /dev/null +++ b/docs/framework/solid/reference/interfaces/InfiniteQueryObserverOptions.md @@ -0,0 +1,59 @@ +--- +id: InfiniteQueryObserverOptions +title: InfiniteQueryObserverOptions +--- + +Defined in: [QueryClient.ts:62](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClient.ts#L62) + +The core `InfiniteQueryObserverOptions`, with Solid's `reconcile` option added. + +## Extends + +- `OmitKeyof`\<`QueryCoreInfiniteQueryObserverOptions`\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>, `"structuralSharing"`\> + +## Type Parameters + +### TQueryFnData + +`TQueryFnData` = `unknown` + +The type of a single page, as your `queryFn` resolves it. + +### TError + +`TError` = `DefaultError` + +The type of errors your `queryFn` may throw. + +### TData + +`TData` = `TQueryFnData` + +The type `data` ends up as after `select` runs. + +### TQueryKey + +`TQueryKey` *extends* `QueryKey` = `QueryKey` + +The type of your `queryKey`. + +### TPageParam + +`TPageParam` = `unknown` + +The type of the parameter passed to `queryFn` to fetch a given page. + +## Properties + +### reconcile? + +```ts +optional reconcile: string | false | (oldData, newData) => TData; +``` + +Defined in: [QueryClient.ts:84](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClient.ts#L84) + +Set this to a reconciliation key to enable reconciliation between query results. +Set this to `false` to disable reconciliation between query results. +Set this to a function which accepts the old and new data and returns resolved data of the same type to implement custom reconciliation logic. +Defaults reconciliation to false. diff --git a/docs/framework/solid/reference/interfaces/InfiniteQueryOptions.md b/docs/framework/solid/reference/interfaces/InfiniteQueryOptions.md new file mode 100644 index 0000000000..1b0803cef0 --- /dev/null +++ b/docs/framework/solid/reference/interfaces/InfiniteQueryOptions.md @@ -0,0 +1,106 @@ +--- +id: InfiniteQueryOptions +title: InfiniteQueryOptions +--- + +Defined in: [types.ts:157](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L157) + +The options accepted by `useInfiniteQuery`. + +## Extends + +- `OmitKeyof`\<[`InfiniteQueryObserverOptions`](InfiniteQueryObserverOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>, `"queryKey"` \| `"suspense"`\> + +## Type Parameters + +### TQueryFnData + +`TQueryFnData` = `unknown` + +The type of a single page, as your `queryFn` resolves it. + +### TError + +`TError` = `DefaultError` + +The type of errors your `queryFn` may throw. + +### TData + +`TData` = `TQueryFnData` + +The type `data` ends up as after `select` runs. + +### TQueryKey + +`TQueryKey` *extends* `QueryKey` = `QueryKey` + +The type of your `queryKey`. + +### TPageParam + +`TPageParam` = `unknown` + +The type of the parameter passed to `queryFn` to fetch a given page. + +## Properties + +### deferStream? + +```ts +optional deferStream: boolean; +``` + +Defined in: [types.ts:180](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L180) + +Only applicable while rendering queries on the server with streaming. +Set `deferStream` to `true` to wait for the query to resolve on the server before flushing the stream. +This can be useful to avoid sending a loading state to the client before the query has resolved. +Defaults to `false`. + +*** + +### queryKey + +```ts +queryKey: TQueryKey; +``` + +Defined in: [types.ts:173](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L173) + +*** + +### reconcile? + +```ts +optional reconcile: string | false | (oldData, newData) => TData; +``` + +Defined in: [QueryClient.ts:84](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClient.ts#L84) + +Set this to a reconciliation key to enable reconciliation between query results. +Set this to `false` to disable reconciliation between query results. +Set this to a function which accepts the old and new data and returns resolved data of the same type to implement custom reconciliation logic. +Defaults reconciliation to false. + +#### Inherited from + +```ts +OmitKeyof.reconcile +``` + +*** + +### ~~suspense?~~ + +```ts +optional suspense: boolean; +``` + +Defined in: [types.ts:186](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L186) + +#### Deprecated + +The `suspense` option has been deprecated in v5 and will be removed in the next major version. +The `data` property on useInfiniteQuery is a SolidJS resource and will automatically suspend when the data is loading. +Setting `suspense` to `false` will be a no-op. diff --git a/docs/framework/solid/reference/interfaces/MutationOptions.md b/docs/framework/solid/reference/interfaces/MutationOptions.md new file mode 100644 index 0000000000..de6ae1a0fc --- /dev/null +++ b/docs/framework/solid/reference/interfaces/MutationOptions.md @@ -0,0 +1,38 @@ +--- +id: MutationOptions +title: MutationOptions +--- + +Defined in: [types.ts:241](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L241) + +The options accepted by `useMutation` and `mutationOptions`. + +## Extends + +- `OmitKeyof`\<`MutationObserverOptions`\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>, `"_defaulted"`\> + +## Type Parameters + +### TData + +`TData` = `unknown` + +The type your `mutationFn` resolves to. + +### TError + +`TError` = `DefaultError` + +The type of errors your `mutationFn` may throw. + +### TVariables + +`TVariables` = `void` + +The type of the variables your `mutationFn` accepts. + +### TOnMutateResult + +`TOnMutateResult` = `unknown` + +The type returned by `onMutate`, passed on to `onSuccess`/`onError`/`onSettled`. diff --git a/docs/framework/solid/reference/interfaces/QueryClientConfig.md b/docs/framework/solid/reference/interfaces/QueryClientConfig.md new file mode 100644 index 0000000000..f5843d7066 --- /dev/null +++ b/docs/framework/solid/reference/interfaces/QueryClientConfig.md @@ -0,0 +1,28 @@ +--- +id: QueryClientConfig +title: QueryClientConfig +--- + +Defined in: [QueryClient.ts:105](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClient.ts#L105) + +The config accepted by `new QueryClient(config)`, with Solid's extended [DefaultOptions](DefaultOptions.md). + +## Extends + +- `QueryClientConfig` + +## Properties + +### defaultOptions? + +```ts +optional defaultOptions: DefaultOptions; +``` + +Defined in: [QueryClient.ts:106](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClient.ts#L106) + +#### Overrides + +```ts +QueryCoreClientConfig.defaultOptions +``` diff --git a/docs/framework/solid/reference/interfaces/QueryObserverOptions.md b/docs/framework/solid/reference/interfaces/QueryObserverOptions.md new file mode 100644 index 0000000000..7d5c95448a --- /dev/null +++ b/docs/framework/solid/reference/interfaces/QueryObserverOptions.md @@ -0,0 +1,66 @@ +--- +id: QueryObserverOptions +title: QueryObserverOptions +--- + +Defined in: [QueryClient.ts:23](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClient.ts#L23) + +The core `QueryObserverOptions`, with Solid's `reconcile` option added. + +## Extends + +- `OmitKeyof`\<`QueryCoreObserverOptions`\<`TQueryFnData`, `TError`, `TData`, `TQueryData`, `TQueryKey`, `TPageParam`\>, `"structuralSharing"`\> + +## Type Parameters + +### TQueryFnData + +`TQueryFnData` = `unknown` + +The type your `queryFn` resolves to. + +### TError + +`TError` = `DefaultError` + +The type of errors your `queryFn` may throw. + +### TData + +`TData` = `TQueryFnData` + +The type `data` ends up as after `select` runs. + +### TQueryData + +`TQueryData` = `TQueryFnData` + +The type of the data actually held in the query cache. + +### TQueryKey + +`TQueryKey` *extends* `QueryKey` = `QueryKey` + +The type of your `queryKey`. + +### TPageParam + +`TPageParam` = `never` + +The type of the parameter passed to `queryFn` to fetch a given page, when this type +is shared with an infinite query's observer options. Defaults to `never` for regular queries. + +## Properties + +### reconcile? + +```ts +optional reconcile: string | false | (oldData, newData) => TData; +``` + +Defined in: [QueryClient.ts:47](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClient.ts#L47) + +Set this to a reconciliation key to enable reconciliation between query results. +Set this to `false` to disable reconciliation between query results. +Set this to a function which accepts the old and new data and returns resolved data of the same type to implement custom reconciliation logic. +Defaults reconciliation to false. diff --git a/docs/framework/solid/reference/interfaces/QueryOptions.md b/docs/framework/solid/reference/interfaces/QueryOptions.md new file mode 100644 index 0000000000..83f5cc4093 --- /dev/null +++ b/docs/framework/solid/reference/interfaces/QueryOptions.md @@ -0,0 +1,97 @@ +--- +id: QueryOptions +title: QueryOptions +--- + +Defined in: [types.ts:68](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L68) + +The options accepted by `useQuery` and `queryOptions`. + +## Extends + +- [`UseBaseQueryOptions`](UseBaseQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryFnData`, `TQueryKey`\> + +## Type Parameters + +### TQueryFnData + +`TQueryFnData` = `unknown` + +The type your `queryFn` resolves to. + +### TError + +`TError` = `DefaultError` + +The type of errors your `queryFn` may throw. + +### TData + +`TData` = `TQueryFnData` + +The type `data` ends up as after `select` runs. Defaults to `TQueryFnData` when no +`select` is used. + +### TQueryKey + +`TQueryKey` *extends* `QueryKey` = `QueryKey` + +The type of your `queryKey`. + +## Properties + +### deferStream? + +```ts +optional deferStream: boolean; +``` + +Defined in: [types.ts:50](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L50) + +Only applicable while rendering queries on the server with streaming. +Set `deferStream` to `true` to wait for the query to resolve on the server before flushing the stream. +This can be useful to avoid sending a loading state to the client before the query has resolved. +Defaults to `false`. + +#### Inherited from + +[`UseBaseQueryOptions`](UseBaseQueryOptions.md).[`deferStream`](UseBaseQueryOptions.md#deferstream) + +*** + +### reconcile? + +```ts +optional reconcile: string | false | (oldData, newData) => TData; +``` + +Defined in: [QueryClient.ts:47](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClient.ts#L47) + +Set this to a reconciliation key to enable reconciliation between query results. +Set this to `false` to disable reconciliation between query results. +Set this to a function which accepts the old and new data and returns resolved data of the same type to implement custom reconciliation logic. +Defaults reconciliation to false. + +#### Inherited from + +[`UseBaseQueryOptions`](UseBaseQueryOptions.md).[`reconcile`](UseBaseQueryOptions.md#reconcile) + +*** + +### ~~suspense?~~ + +```ts +optional suspense: boolean; +``` + +Defined in: [types.ts:56](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L56) + +#### Deprecated + +The `suspense` option has been deprecated in v5 and will be removed in the next major version. +The `data` property on useQuery is a SolidJS resource and will automatically suspend when the data is loading. +Setting `suspense` to `false` will be a no-op. + +#### Inherited from + +[`UseBaseQueryOptions`](UseBaseQueryOptions.md).[`suspense`](UseBaseQueryOptions.md#suspense) diff --git a/docs/framework/solid/reference/interfaces/UseBaseQueryOptions.md b/docs/framework/solid/reference/interfaces/UseBaseQueryOptions.md new file mode 100644 index 0000000000..c26094dfd3 --- /dev/null +++ b/docs/framework/solid/reference/interfaces/UseBaseQueryOptions.md @@ -0,0 +1,103 @@ +--- +id: UseBaseQueryOptions +title: UseBaseQueryOptions +--- + +Defined in: [types.ts:34](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L34) + +The options accepted by `useQuery`. Extends [QueryObserverOptions](QueryObserverOptions.md) from `@tanstack/query-core` with +the `solid-query`-specific `deferStream` and `suspense` options. + +## Extends + +- `OmitKeyof`\<[`QueryObserverOptions`](QueryObserverOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryData`, `TQueryKey`\>, `"suspense"`\> + +## Extended by + +- [`QueryOptions`](QueryOptions.md) + +## Type Parameters + +### TQueryFnData + +`TQueryFnData` = `unknown` + +The type your `queryFn` resolves to. + +### TError + +`TError` = `DefaultError` + +The type of errors your `queryFn` may throw. + +### TData + +`TData` = `TQueryFnData` + +The type `data` ends up as after `select` runs. Defaults to `TQueryFnData` when no +`select` is used. + +### TQueryData + +`TQueryData` = `TQueryFnData` + +The type of the data actually held in the query cache — the input to `select` and +`placeholderData`. Defaults to, and is usually the same as, `TQueryFnData`. + +### TQueryKey + +`TQueryKey` *extends* `QueryKey` = `QueryKey` + +The type of your `queryKey`. + +## Properties + +### deferStream? + +```ts +optional deferStream: boolean; +``` + +Defined in: [types.ts:50](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L50) + +Only applicable while rendering queries on the server with streaming. +Set `deferStream` to `true` to wait for the query to resolve on the server before flushing the stream. +This can be useful to avoid sending a loading state to the client before the query has resolved. +Defaults to `false`. + +*** + +### reconcile? + +```ts +optional reconcile: string | false | (oldData, newData) => TData; +``` + +Defined in: [QueryClient.ts:47](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClient.ts#L47) + +Set this to a reconciliation key to enable reconciliation between query results. +Set this to `false` to disable reconciliation between query results. +Set this to a function which accepts the old and new data and returns resolved data of the same type to implement custom reconciliation logic. +Defaults reconciliation to false. + +#### Inherited from + +```ts +OmitKeyof.reconcile +``` + +*** + +### ~~suspense?~~ + +```ts +optional suspense: boolean; +``` + +Defined in: [types.ts:56](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L56) + +#### Deprecated + +The `suspense` option has been deprecated in v5 and will be removed in the next major version. +The `data` property on useQuery is a SolidJS resource and will automatically suspend when the data is loading. +Setting `suspense` to `false` will be a no-op. diff --git a/docs/framework/solid/reference/mutationOptions.md b/docs/framework/solid/reference/mutationOptions.md deleted file mode 100644 index 0fa145a890..0000000000 --- a/docs/framework/solid/reference/mutationOptions.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -id: mutationOptions -title: mutationOptions ---- - -```tsx -mutationOptions({ - mutationFn, - ...options, -}) -``` - -**Options** - -You can generally pass everything to `mutationOptions` that you can also pass to [`useMutation`](./useMutation.md). diff --git a/docs/framework/solid/reference/queryOptions.md b/docs/framework/solid/reference/queryOptions.md deleted file mode 100644 index f6f0ac7f2e..0000000000 --- a/docs/framework/solid/reference/queryOptions.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -id: queryOptions -title: queryOptions ---- - -```tsx -queryOptions({ - queryKey, - ...options, -}) -``` - -**Options** - -You can generally pass everything to `queryOptions` that you can also pass to [`useQuery`](./useQuery.md). These options can be shared across hooks and imperative APIs such as `queryClient.query`. - -- `queryKey: QueryKey` - - **Required** - - The query key to generate options for. -[//]: # 'Materials' - -## Further reading - -To learn more about `QueryOptions`, have a look at [this article by TkDodo The Query Options API](https://tkdodo.eu/blog/the-query-options-api). - -[//]: # 'Materials' diff --git a/docs/framework/solid/reference/type-aliases/DefinedInitialDataInfiniteOptions.md b/docs/framework/solid/reference/type-aliases/DefinedInitialDataInfiniteOptions.md new file mode 100644 index 0000000000..e01fb72d53 --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/DefinedInitialDataInfiniteOptions.md @@ -0,0 +1,46 @@ +--- +id: DefinedInitialDataInfiniteOptions +title: DefinedInitialDataInfiniteOptions +--- + +```ts +type DefinedInitialDataInfiniteOptions = Accessor & object>; +``` + +Defined in: [infiniteQueryOptions.ts:48](https://github.com/TanStack/query/blob/main/packages/solid-query/src/infiniteQueryOptions.ts#L48) + +The options accepted by the `infiniteQueryOptions` overload selected when `initialData` is set — `data` is +never `undefined`. + +## Type Parameters + +### TQueryFnData + +`TQueryFnData` + +The type of a single page, as your `queryFn` resolves it. + +### TError + +`TError` = `DefaultError` + +The type of errors your `queryFn` may throw. + +### TData + +`TData` = `InfiniteData`\<`TQueryFnData`\> + +The type `data` ends up as after `select` runs — defaults to `InfiniteData`, +the shape of all fetched pages plus their page params. + +### TQueryKey + +`TQueryKey` *extends* `QueryKey` = `QueryKey` + +The type of your `queryKey`. + +### TPageParam + +`TPageParam` = `unknown` + +The type of the parameter passed to `queryFn` to fetch a given page. diff --git a/docs/framework/solid/reference/type-aliases/DefinedInitialDataOptions.md b/docs/framework/solid/reference/type-aliases/DefinedInitialDataOptions.md new file mode 100644 index 0000000000..0a0a224bf4 --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/DefinedInitialDataOptions.md @@ -0,0 +1,39 @@ +--- +id: DefinedInitialDataOptions +title: DefinedInitialDataOptions +--- + +```ts +type DefinedInitialDataOptions = Accessor & object>; +``` + +Defined in: [queryOptions.ts:40](https://github.com/TanStack/query/blob/main/packages/solid-query/src/queryOptions.ts#L40) + +The options accepted by the `queryOptions` overload selected when `initialData` is set — `data` is never +`undefined`. + +## Type Parameters + +### TQueryFnData + +`TQueryFnData` = `unknown` + +The type your `queryFn` resolves to. + +### TError + +`TError` = `DefaultError` + +The type of errors your `queryFn` may throw. + +### TData + +`TData` = `TQueryFnData` + +The type `data` ends up as after `select` runs. + +### TQueryKey + +`TQueryKey` *extends* `QueryKey` = `QueryKey` + +The type of your `queryKey`. diff --git a/docs/framework/solid/reference/type-aliases/DefinedUseBaseQueryResult.md b/docs/framework/solid/reference/type-aliases/DefinedUseBaseQueryResult.md new file mode 100644 index 0000000000..b26b9bc63e --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/DefinedUseBaseQueryResult.md @@ -0,0 +1,26 @@ +--- +id: DefinedUseBaseQueryResult +title: DefinedUseBaseQueryResult +--- + +```ts +type DefinedUseBaseQueryResult = DefinedQueryObserverResult; +``` + +Defined in: [types.ts:131](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L131) + +The object `useQuery` returns when `initialData` guarantees `data` is never `undefined`. + +## Type Parameters + +### TData + +`TData` = `unknown` + +The type `data` ends up as, after `select` runs (if set). + +### TError + +`TError` = `DefaultError` + +The type of errors this query may hold. diff --git a/docs/framework/solid/reference/type-aliases/DefinedUseInfiniteQueryResult.md b/docs/framework/solid/reference/type-aliases/DefinedUseInfiniteQueryResult.md new file mode 100644 index 0000000000..b854a75b36 --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/DefinedUseInfiniteQueryResult.md @@ -0,0 +1,26 @@ +--- +id: DefinedUseInfiniteQueryResult +title: DefinedUseInfiniteQueryResult +--- + +```ts +type DefinedUseInfiniteQueryResult = DefinedInfiniteQueryObserverResult; +``` + +Defined in: [types.ts:227](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L227) + +The object `useInfiniteQuery` returns when `initialData` guarantees `data` is never `undefined`. + +## Type Parameters + +### TData + +`TData` = `unknown` + +The type `data` ends up as, after `select` runs (if set). + +### TError + +`TError` = `DefaultError` + +The type of errors this query may hold. diff --git a/docs/framework/solid/reference/type-aliases/DefinedUseQueryResult.md b/docs/framework/solid/reference/type-aliases/DefinedUseQueryResult.md new file mode 100644 index 0000000000..c903601dd4 --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/DefinedUseQueryResult.md @@ -0,0 +1,26 @@ +--- +id: DefinedUseQueryResult +title: DefinedUseQueryResult +--- + +```ts +type DefinedUseQueryResult = DefinedUseBaseQueryResult; +``` + +Defined in: [types.ts:142](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L142) + +The object `useQuery` returns when `initialData` guarantees `data` is never `undefined`. + +## Type Parameters + +### TData + +`TData` = `unknown` + +The type `data` ends up as, after `select` runs (if set). + +### TError + +`TError` = `DefaultError` + +The type of errors this query may hold. diff --git a/docs/framework/solid/reference/type-aliases/QueryClientProviderProps.md b/docs/framework/solid/reference/type-aliases/QueryClientProviderProps.md new file mode 100644 index 0000000000..9aa8754676 --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/QueryClientProviderProps.md @@ -0,0 +1,38 @@ +--- +id: QueryClientProviderProps +title: QueryClientProviderProps +--- + +```ts +type QueryClientProviderProps = object; +``` + +Defined in: [QueryClientProvider.tsx:63](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClientProvider.tsx#L63) + +The props accepted by `QueryClientProvider`. + +## Properties + +### children? + +```ts +optional children: JSX.Element; +``` + +Defined in: [QueryClientProvider.tsx:73](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClientProvider.tsx#L73) + +The components that get access to the provided `QueryClient`. + +*** + +### client + +```ts +client: QueryClient; +``` + +Defined in: [QueryClientProvider.tsx:69](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClientProvider.tsx#L69) + +**Required** + +The `QueryClient` instance to provide. diff --git a/docs/framework/solid/reference/type-aliases/UndefinedInitialDataInfiniteOptions.md b/docs/framework/solid/reference/type-aliases/UndefinedInitialDataInfiniteOptions.md new file mode 100644 index 0000000000..477c66c250 --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/UndefinedInitialDataInfiniteOptions.md @@ -0,0 +1,49 @@ +--- +id: UndefinedInitialDataInfiniteOptions +title: UndefinedInitialDataInfiniteOptions +--- + +```ts +type UndefinedInitialDataInfiniteOptions = Accessor & object>; +``` + +Defined in: [infiniteQueryOptions.ts:25](https://github.com/TanStack/query/blob/main/packages/solid-query/src/infiniteQueryOptions.ts#L25) + +The options accepted by the `infiniteQueryOptions` overload selected when no `initialData` is set — `data` +may be `undefined` while the query is `pending`. `infiniteQueryOptions` itself accepts and returns a plain +object (its parameter type is `ReturnType>`, i.e. this `Accessor` +called); Solid's reactivity applies where the result is consumed instead, e.g. +`useInfiniteQuery(() => options)`. + +## Type Parameters + +### TQueryFnData + +`TQueryFnData` + +The type of a single page, as your `queryFn` resolves it. + +### TError + +`TError` = `DefaultError` + +The type of errors your `queryFn` may throw. + +### TData + +`TData` = `InfiniteData`\<`TQueryFnData`\> + +The type `data` ends up as after `select` runs — defaults to `InfiniteData`, +the shape of all fetched pages plus their page params. + +### TQueryKey + +`TQueryKey` *extends* `QueryKey` = `QueryKey` + +The type of your `queryKey`. + +### TPageParam + +`TPageParam` = `unknown` + +The type of the parameter passed to `queryFn` to fetch a given page. diff --git a/docs/framework/solid/reference/type-aliases/UndefinedInitialDataOptions.md b/docs/framework/solid/reference/type-aliases/UndefinedInitialDataOptions.md new file mode 100644 index 0000000000..d74fedfa95 --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/UndefinedInitialDataOptions.md @@ -0,0 +1,41 @@ +--- +id: UndefinedInitialDataOptions +title: UndefinedInitialDataOptions +--- + +```ts +type UndefinedInitialDataOptions = Accessor & object>; +``` + +Defined in: [queryOptions.ts:20](https://github.com/TanStack/query/blob/main/packages/solid-query/src/queryOptions.ts#L20) + +The options accepted by the `queryOptions` overload selected when no `initialData` is set — `data` may be +`undefined` while the query is `pending`. `queryOptions` itself accepts and returns a plain object (its +parameter type is `ReturnType>`, i.e. this `Accessor` called); Solid's +reactivity applies where the result is consumed instead, e.g. `useQuery(() => options)`. + +## Type Parameters + +### TQueryFnData + +`TQueryFnData` = `unknown` + +The type your `queryFn` resolves to. + +### TError + +`TError` = `DefaultError` + +The type of errors your `queryFn` may throw. + +### TData + +`TData` = `TQueryFnData` + +The type `data` ends up as after `select` runs. + +### TQueryKey + +`TQueryKey` *extends* `QueryKey` = `QueryKey` + +The type of your `queryKey`. diff --git a/docs/framework/solid/reference/type-aliases/UseBaseMutationResult.md b/docs/framework/solid/reference/type-aliases/UseBaseMutationResult.md new file mode 100644 index 0000000000..7b3cd4a91a --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/UseBaseMutationResult.md @@ -0,0 +1,52 @@ +--- +id: UseBaseMutationResult +title: UseBaseMutationResult +--- + +```ts +type UseBaseMutationResult = Override, { + mutate: UseMutateFunction; +}> & object; +``` + +Defined in: [types.ts:305](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L305) + +The result of `useMutation`. Same as MutationObserverResult from `@tanstack/query-core`, with +`mutate` narrowed to the fire-and-forget [UseMutateFunction](UseMutateFunction.md) signature, plus the added `mutateAsync`. + +## Type Declaration + +### mutateAsync + +```ts +mutateAsync: UseMutateAsyncFunction; +``` + +Similar to `mutate`, but returns a promise which can be awaited. + +## Type Parameters + +### TData + +`TData` = `unknown` + +The type your `mutationFn` resolves to. + +### TError + +`TError` = `DefaultError` + +The type of errors your `mutationFn` may throw. + +### TVariables + +`TVariables` = `unknown` + +The type of the variable passed to `mutate`/`mutateAsync`. + +### TOnMutateResult + +`TOnMutateResult` = `unknown` + +The type returned by `onMutate`, passed to `onSuccess`/`onError`/`onSettled` as +their `onMutateResult` parameter — useful for optimistic-update rollback data. diff --git a/docs/framework/solid/reference/type-aliases/UseBaseQueryResult.md b/docs/framework/solid/reference/type-aliases/UseBaseQueryResult.md new file mode 100644 index 0000000000..25f70f2343 --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/UseBaseQueryResult.md @@ -0,0 +1,28 @@ +--- +id: UseBaseQueryResult +title: UseBaseQueryResult +--- + +```ts +type UseBaseQueryResult = QueryObserverResult; +``` + +Defined in: [types.ts:108](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L108) + +The object `useQuery` returns when `initialData` isn't set — `data`/`error` may still be `undefined`/`null` +while the query is `pending`. Re-exports QueryObserverResult from `@tanstack/query-core`. +`useInfiniteQuery` returns [UseInfiniteQueryResult](UseInfiniteQueryResult.md) instead. + +## Type Parameters + +### TData + +`TData` = `unknown` + +The type `data` ends up as, after `select` runs (if set). + +### TError + +`TError` = `DefaultError` + +The type of errors this query may hold. diff --git a/docs/framework/solid/reference/type-aliases/UseInfiniteQueryOptions.md b/docs/framework/solid/reference/type-aliases/UseInfiniteQueryOptions.md new file mode 100644 index 0000000000..ea549f2c22 --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/UseInfiniteQueryOptions.md @@ -0,0 +1,45 @@ +--- +id: UseInfiniteQueryOptions +title: UseInfiniteQueryOptions +--- + +```ts +type UseInfiniteQueryOptions = Accessor>; +``` + +Defined in: [types.ts:199](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L199) + +The accessor `useInfiniteQuery` expects as its first argument — Solid re-evaluates it reactively, so +`queryKey` and other options can depend on signals. + +## Type Parameters + +### TQueryFnData + +`TQueryFnData` = `unknown` + +The type of a single page, as your `queryFn` resolves it. + +### TError + +`TError` = `DefaultError` + +The type of errors your `queryFn` may throw. + +### TData + +`TData` = `TQueryFnData` + +The type `data` ends up as after `select` runs. + +### TQueryKey + +`TQueryKey` *extends* `QueryKey` = `QueryKey` + +The type of your `queryKey`. + +### TPageParam + +`TPageParam` = `unknown` + +The type of the parameter passed to `queryFn` to fetch a given page. diff --git a/docs/framework/solid/reference/type-aliases/UseInfiniteQueryResult.md b/docs/framework/solid/reference/type-aliases/UseInfiniteQueryResult.md new file mode 100644 index 0000000000..27bbb6af67 --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/UseInfiniteQueryResult.md @@ -0,0 +1,27 @@ +--- +id: UseInfiniteQueryResult +title: UseInfiniteQueryResult +--- + +```ts +type UseInfiniteQueryResult = InfiniteQueryObserverResult; +``` + +Defined in: [types.ts:216](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L216) + +The object `useInfiniteQuery` returns — `data`/`error` may still be `undefined`/`null` while the query is +`pending`. + +## Type Parameters + +### TData + +`TData` = `unknown` + +The type `data` ends up as, after `select` runs (if set). + +### TError + +`TError` = `DefaultError` + +The type of errors this query may hold. diff --git a/docs/framework/solid/reference/type-aliases/UseMutateAsyncFunction.md b/docs/framework/solid/reference/type-aliases/UseMutateAsyncFunction.md new file mode 100644 index 0000000000..5c8b2b61f8 --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/UseMutateAsyncFunction.md @@ -0,0 +1,40 @@ +--- +id: UseMutateAsyncFunction +title: UseMutateAsyncFunction +--- + +```ts +type UseMutateAsyncFunction = MutateFunction; +``` + +Defined in: [types.ts:288](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L288) + +The type of `mutateAsync`, as returned by `useMutation`. Similar to [UseMutateFunction](UseMutateFunction.md), but returns a +promise which can be awaited. + +## Type Parameters + +### TData + +`TData` = `unknown` + +The type your `mutationFn` resolves to. + +### TError + +`TError` = `DefaultError` + +The type of errors your `mutationFn` may throw. + +### TVariables + +`TVariables` = `void` + +The type of the variable passed to `mutateAsync`. + +### TOnMutateResult + +`TOnMutateResult` = `unknown` + +The type returned by `onMutate`, passed to `onSuccess`/`onError`/`onSettled` as +their `onMutateResult` parameter — useful for optimistic-update rollback data. diff --git a/docs/framework/solid/reference/type-aliases/UseMutateFunction.md b/docs/framework/solid/reference/type-aliases/UseMutateFunction.md new file mode 100644 index 0000000000..02efe15eea --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/UseMutateFunction.md @@ -0,0 +1,38 @@ +--- +id: UseMutateFunction +title: UseMutateFunction +--- + +```ts +type UseMutateFunction = (...args) => void; +``` + +Defined in: [types.ts:267](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L267) + +## Type Parameters + +### TData + +`TData` = `unknown` + +### TError + +`TError` = `DefaultError` + +### TVariables + +`TVariables` = `void` + +### TOnMutateResult + +`TOnMutateResult` = `unknown` + +## Parameters + +### args + +...`Parameters`\<`MutateFunction`\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>\> + +## Returns + +`void` diff --git a/docs/framework/solid/reference/type-aliases/UseMutationOptions.md b/docs/framework/solid/reference/type-aliases/UseMutationOptions.md new file mode 100644 index 0000000000..bf6fda3557 --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/UseMutationOptions.md @@ -0,0 +1,39 @@ +--- +id: UseMutationOptions +title: UseMutationOptions +--- + +```ts +type UseMutationOptions = Accessor>; +``` + +Defined in: [types.ts:260](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L260) + +The accessor `useMutation` expects as its first argument — Solid re-evaluates it reactively, so callbacks +and other options can depend on signals. + +## Type Parameters + +### TData + +`TData` = `unknown` + +The type your `mutationFn` resolves to. + +### TError + +`TError` = `DefaultError` + +The type of errors your `mutationFn` may throw. + +### TVariables + +`TVariables` = `void` + +The type of the variables your `mutationFn` accepts. + +### TOnMutateResult + +`TOnMutateResult` = `unknown` + +The type returned by `onMutate`, passed on to `onSuccess`/`onError`/`onSettled`. diff --git a/docs/framework/solid/reference/type-aliases/UseMutationResult.md b/docs/framework/solid/reference/type-aliases/UseMutationResult.md new file mode 100644 index 0000000000..c3d1e3b4f4 --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/UseMutationResult.md @@ -0,0 +1,39 @@ +--- +id: UseMutationResult +title: UseMutationResult +--- + +```ts +type UseMutationResult = UseBaseMutationResult; +``` + +Defined in: [types.ts:334](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L334) + +The result of `useMutation`. Same as [UseBaseMutationResult](UseBaseMutationResult.md). + +## Type Parameters + +### TData + +`TData` = `unknown` + +The type your `mutationFn` resolves to. + +### TError + +`TError` = `DefaultError` + +The type of errors your `mutationFn` may throw. + +### TVariables + +`TVariables` = `unknown` + +The type of the variable passed to `mutate`/`mutateAsync`. + +### TOnMutateResult + +`TOnMutateResult` = `unknown` + +The type returned by `onMutate`, passed to `onSuccess`/`onError`/`onSettled` as +their `onMutateResult` parameter — useful for optimistic-update rollback data. diff --git a/docs/framework/solid/reference/type-aliases/UseQueryOptions.md b/docs/framework/solid/reference/type-aliases/UseQueryOptions.md new file mode 100644 index 0000000000..66e2b0e8a8 --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/UseQueryOptions.md @@ -0,0 +1,40 @@ +--- +id: UseQueryOptions +title: UseQueryOptions +--- + +```ts +type UseQueryOptions = Accessor>; +``` + +Defined in: [types.ts:91](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L91) + +The accessor `useQuery` expects as its first argument — Solid re-evaluates it reactively, so `queryKey` and +other options can depend on signals. + +## Type Parameters + +### TQueryFnData + +`TQueryFnData` = `unknown` + +The type your `queryFn` resolves to. + +### TError + +`TError` = `DefaultError` + +The type of errors your `queryFn` may throw. + +### TData + +`TData` = `TQueryFnData` + +The type `data` ends up as after `select` runs. Defaults to `TQueryFnData` when no +`select` is used. + +### TQueryKey + +`TQueryKey` *extends* `QueryKey` = `QueryKey` + +The type of your `queryKey`. diff --git a/docs/framework/solid/reference/type-aliases/UseQueryResult.md b/docs/framework/solid/reference/type-aliases/UseQueryResult.md new file mode 100644 index 0000000000..c88e14178a --- /dev/null +++ b/docs/framework/solid/reference/type-aliases/UseQueryResult.md @@ -0,0 +1,27 @@ +--- +id: UseQueryResult +title: UseQueryResult +--- + +```ts +type UseQueryResult = UseBaseQueryResult; +``` + +Defined in: [types.ts:120](https://github.com/TanStack/query/blob/main/packages/solid-query/src/types.ts#L120) + +The object `useQuery` returns — `data`/`error` may still be `undefined`/`null` while the query is +`pending`. + +## Type Parameters + +### TData + +`TData` = `unknown` + +The type `data` ends up as, after `select` runs (if set). + +### TError + +`TError` = `DefaultError` + +The type of errors this query may hold. diff --git a/docs/framework/solid/reference/useInfiniteQuery.md b/docs/framework/solid/reference/useInfiniteQuery.md deleted file mode 100644 index 8ae5861e08..0000000000 --- a/docs/framework/solid/reference/useInfiniteQuery.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -id: useInfiniteQuery -title: useInfiniteQuery ---- - -```tsx -const { - fetchNextPage, - fetchPreviousPage, - hasNextPage, - hasPreviousPage, - isFetchingNextPage, - isFetchingPreviousPage, - ...result -} = useInfiniteQuery(() => ({ - queryKey, - queryFn: ({ pageParam }) => fetchPage(pageParam), - initialPageParam: 1, - ...options, - getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => - lastPage.nextCursor, - getPreviousPageParam: (firstPage, allPages, firstPageParam, allPageParams) => - firstPage.prevCursor, -})) -``` - -**Options** - -The options for `useInfiniteQuery` are identical to the [`useQuery` hook](../reference/useQuery.md) with the addition of the following: - -- `queryFn: (context: QueryFunctionContext) => Promise` - - **Required, but only if no default query function has been defined** [`defaultQueryFn`](../guides/default-query-function.md) - - The function that the query will use to request data. - - Receives a [QueryFunctionContext](../guides/query-functions.md#queryfunctioncontext) - - Must return a promise that will either resolve data or throw an error. -- `initialPageParam: TPageParam` - - **Required** - - The default page param to use when fetching the first page. -- `getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => TPageParam | undefined | null` - - **Required** - - When new data is received for this query, this function receives both the last page of the infinite list of data and the full array of all pages, as well as pageParam information. - - It should return a **single variable** that will be passed as `pageParam` on your query function's context object (e.g. `queryFn: ({ pageParam }) => ...`). - - Return `undefined` or `null` to indicate there is no next page available. -- `getPreviousPageParam: (firstPage, allPages, firstPageParam, allPageParams) => TPageParam | undefined | null` - - When new data is received for this query, this function receives both the first page of the infinite list of data and the full array of all pages, as well as pageParam information. - - It should return a **single variable** that will be passed as `pageParam` on your query function's context object (e.g. `queryFn: ({ pageParam }) => ...`). - - Return `undefined` or `null`to indicate there is no previous page available. -- `maxPages: number | undefined` - - The maximum number of pages to store in the infinite query data. - - When the maximum number of pages is reached, fetching a new page will result in the removal of either the first or last page from the pages array, depending on the specified direction. - - If `undefined` or equals `0`, the number of pages is unlimited - - Default value is `undefined` - - `getNextPageParam` and `getPreviousPageParam` must be properly defined if `maxPages` value is greater than `0` to allow fetching a page in both directions when needed. - -**Returns** - -The returned properties for `useInfiniteQuery` are identical to the [`useQuery` hook](../reference/useQuery.md), with the addition of the following properties and a small difference in `isRefetching` and `isRefetchError`: - -- `data.pages: TData[]` - - Array containing all pages. -- `data.pageParams: unknown[]` - - Array containing all page params. -- `isFetchingNextPage: boolean` - - Will be `true` while fetching the next page with `fetchNextPage`. -- `isFetchingPreviousPage: boolean` - - Will be `true` while fetching the previous page with `fetchPreviousPage`. -- `fetchNextPage: (options?: FetchNextPageOptions) => Promise` - - This function allows you to fetch the next "page" of results. - - `options.cancelRefetch: boolean` if set to `true`, calling `fetchNextPage` repeatedly will invoke `queryFn` every time, whether the previous - invocation has resolved or not. Also, the result from previous invocations will be ignored. If set to `false`, calling `fetchNextPage` - repeatedly won't have any effect until the first invocation has resolved. Default is `true`. -- `fetchPreviousPage: (options?: FetchPreviousPageOptions) => Promise` - - This function allows you to fetch the previous "page" of results. - - `options.cancelRefetch: boolean` same as for `fetchNextPage`. -- `hasNextPage: boolean` - - Will be `true` if there is a next page to be fetched (known via the `getNextPageParam` option). -- `hasPreviousPage: boolean` - - Will be `true` if there is a previous page to be fetched (known via the `getPreviousPageParam` option). -- `isFetchNextPageError: boolean` - - Will be `true` if the query failed while fetching the next page. -- `isFetchPreviousPageError: boolean` - - Will be `true` if the query failed while fetching the previous page. -- `isRefetching: boolean` - - Will be `true` whenever a background refetch is in-flight, which _does not_ include initial `pending` or fetching of next or previous page - - Is the same as `isFetching && !isPending && !isFetchingNextPage && !isFetchingPreviousPage` -- `isRefetchError: boolean` - - Will be `true` if the query failed while refetching a page. -Keep in mind that imperative fetch calls, such as `fetchNextPage`, may interfere with the default refetch behaviour, resulting in outdated data. Make sure to call these functions only in response to user actions, or add conditions like `hasNextPage && !isFetching`. diff --git a/docs/framework/solid/reference/useIsFetching.md b/docs/framework/solid/reference/useIsFetching.md deleted file mode 100644 index 02ce5f1833..0000000000 --- a/docs/framework/solid/reference/useIsFetching.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -id: useIsFetching -title: useIsFetching ---- - -`useIsFetching` is an optional hook that returns the `number` of the queries that your application is loading or fetching in the background (useful for app-wide loading indicators). - -```tsx -import { useIsFetching } from '@tanstack/solid-query' -// How many queries are fetching? -const isFetching = useIsFetching() -isFetching() -// How many queries matching the posts prefix are fetching? -const isFetchingPosts = useIsFetching(() => ({ queryKey: ['posts'] })) -isFetchingPosts() -``` - -**Options** - -- `filters?: Accessor`: [Query Filters](../guides/filters.md#query-filters) -- `queryClient?: Accessor` - - Use this to use a custom QueryClient. Otherwise, the one from the nearest context will be used. - -**Returns** - -- `isFetching: Accessor` - - Will resolve to the `number` of the queries that your application is currently loading or fetching in the background. diff --git a/docs/framework/solid/reference/useIsMutating.md b/docs/framework/solid/reference/useIsMutating.md deleted file mode 100644 index 5711d84d53..0000000000 --- a/docs/framework/solid/reference/useIsMutating.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -id: useIsMutating -title: useIsMutating ---- - -`useIsMutating` is an optional hook that returns the `number` of mutations that your application is currently in a `pending` state with (useful for app-wide loading indicators). - -```tsx -import { useIsMutating } from '@tanstack/solid-query' -// How many mutations are pending? -const isMutating = useIsMutating() -isMutating() -// How many mutations matching the posts prefix are pending? -const isMutatingPosts = useIsMutating(() => ({ mutationKey: ['posts'] })) -isMutatingPosts() -``` - -**Options** - -- `filters?: Accessor`: [Mutation Filters](../guides/filters.md#mutation-filters) -- `queryClient?: Accessor` - - Use this to use a custom QueryClient. Otherwise, the one from the nearest context will be used. - -**Returns** - -- `isMutating: Accessor` - - Will resolve to the `number` of the mutations that your application is currently pending with. diff --git a/docs/framework/solid/reference/useMutation.md b/docs/framework/solid/reference/useMutation.md deleted file mode 100644 index 0b0d99b989..0000000000 --- a/docs/framework/solid/reference/useMutation.md +++ /dev/null @@ -1,161 +0,0 @@ ---- -id: useMutation -title: useMutation ---- - -```tsx -const { - data, - error, - isError, - isIdle, - isPending, - isPaused, - isSuccess, - failureCount, - failureReason, - mutate, - mutateAsync, - reset, - status, - submittedAt, - variables, -} = useMutation( - () => ({ - mutationFn, - gcTime, - meta, - mutationKey, - networkMode, - onError, - onMutate, - onSettled, - onSuccess, - retry, - retryDelay, - scope, - throwOnError, - }), - () => queryClient, -) - -mutate(variables, { - onError, - onSettled, - onSuccess, -}) -``` - -**Parameter1 (Options)** - -- `mutationFn: (variables: TVariables, context: MutationFunctionContext) => Promise` - - **Required, but only if no default mutation function has been defined** - - A function that performs an asynchronous task and returns a promise. - - `variables` is an object that `mutate` will pass to your `mutationFn` - - `context` is an object that `mutate` will pass to your `mutationFn`. Contains reference to `QueryClient`, `mutationKey` and optional `meta` object. -- `gcTime: number | Infinity` - - The time in milliseconds that unused/inactive cache data remains in memory. When a mutation's cache becomes unused or inactive, that cache data will be garbage collected after this duration. When different cache times are specified, the longest one will be used. - - If set to `Infinity`, will disable garbage collection - - Note: the maximum allowed time is about [24 days](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value), although it is possible to work around this limit using [timeoutManager.setTimeoutProvider](../../../reference/timeoutManager.md#timeoutmanagersettimeoutprovider). -- `mutationKey: unknown[]` - - Optional - - A mutation key can be set to inherit defaults set with `queryClient.setMutationDefaults`. -- `networkMode: 'online' | 'always' | 'offlineFirst'` - - Optional - - defaults to `'online'` - - see [Network Mode](../guides/network-mode.md) for more information. -- `onMutate: (variables: TVariables, context: MutationFunctionContext) => Promise | TOnMutateResult | void` - - Optional - - This function will fire before the mutation function is fired and is passed the same variables the mutation function would receive - - Useful to perform optimistic updates to a resource in hopes that the mutation succeeds - - The value returned from this function will be passed to both the `onError` and `onSettled` functions in the event of a mutation failure and can be useful for rolling back optimistic updates. -- `onSuccess: (data: TData, variables: TVariables, onMutateResult: TOnMutateResult | undefined, context: MutationFunctionContext) => Promise | unknown` - - Optional - - This function will fire when the mutation is successful and will be passed the mutation's result. - - If a promise is returned, it will be awaited and resolved before proceeding -- `onError: (err: TError, variables: TVariables, onMutateResult: TOnMutateResult | undefined, context: MutationFunctionContext) => Promise | unknown` - - Optional - - This function will fire if the mutation encounters an error and will be passed the error. - - If a promise is returned, it will be awaited and resolved before proceeding -- `onSettled: (data: TData | undefined, error: TError | null, variables: TVariables, onMutateResult: TOnMutateResult | undefined, context: MutationFunctionContext) => Promise | unknown` - - Optional - - This function will fire when the mutation is either successfully fetched or encounters an error and be passed either the data or error - - If a promise is returned, it will be awaited and resolved before proceeding -- `retry: boolean | number | (failureCount: number, error: TError) => boolean` - - Defaults to `0`. - - If `false`, failed mutations will not retry. - - If `true`, failed mutations will retry infinitely. - - If set to an `number`, e.g. `3`, failed mutations will retry until the failed mutations count meets that number. -- `retryDelay: number | (retryAttempt: number, error: TError) => number` - - This function receives a `retryAttempt` integer and the actual Error and returns the delay to apply before the next attempt in milliseconds. - - A function like `attempt => Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 30 * 1000)` applies exponential backoff. - - A function like `attempt => attempt * 1000` applies linear backoff. -- `scope: { id: string }` - - Optional - - Defaults to a unique id (so that all mutations run in parallel) - - Mutations with the same scope id will run in serial -- `throwOnError: undefined | boolean | (error: TError) => boolean` - - Set this to `true` if you want mutation errors to be thrown in the render phase and propagate to the nearest error boundary - - Set this to `false` to disable the behavior of throwing errors to the error boundary. - - If set to a function, it will be passed the error and should return a boolean indicating whether to show the error in an error boundary (`true`) or return the error as state (`false`) -- `meta: Record` - - Optional - - If set, stores additional information on the mutation cache entry that can be used as needed. It will be accessible wherever the `mutation` is available (eg. `onError`, `onSuccess` functions of the `MutationCache`). - -**Parameter2 (QueryClient)** - -- `queryClient?: Accessor` - - Use this to use a custom QueryClient. Otherwise, the one from the nearest context will be used. - -**Returns** - -- `mutate: (variables: TVariables, { onSuccess, onSettled, onError }) => void` - - The mutation function you can call with variables to trigger the mutation and optionally hooks on additional callback options. - - `variables: TVariables` - - Optional - - The variables object to pass to the `mutationFn`. - - `onSuccess: (data: TData, variables: TVariables, onMutateResult: TOnMutateResult | undefined, context: MutationFunctionContext) => void` - - Optional - - This function will fire when the mutation is successful and will be passed the mutation's result. - - Void function, the returned value will be ignored - - `onError: (err: TError, variables: TVariables, onMutateResult: TOnMutateResult | undefined, context: MutationFunctionContext) => void` - - Optional - - This function will fire if the mutation encounters an error and will be passed the error. - - Void function, the returned value will be ignored - - `onSettled: (data: TData | undefined, error: TError | null, variables: TVariables, onMutateResult: TOnMutateResult | undefined, context: MutationFunctionContext) => void` - - Optional - - This function will fire when the mutation is either successfully fetched or encounters an error and be passed either the data or error - - Void function, the returned value will be ignored - - If you make multiple requests, `onSuccess` will fire only after the latest call you've made. -- `mutateAsync: (variables: TVariables, { onSuccess, onSettled, onError }) => Promise` - - Similar to `mutate` but returns a promise which can be awaited. -- `status: MutationStatus` - - Will be: - - `idle` initial status prior to the mutation function executing. - - `pending` if the mutation is currently executing. - - `error` if the last mutation attempt resulted in an error. - - `success` if the last mutation attempt was successful. -- `isIdle`, `isPending`, `isSuccess`, `isError`: boolean variables derived from `status` -- `isPaused: boolean` - - will be `true` if the mutation has been `paused` - - see [Network Mode](../guides/network-mode.md) for more information. -- `data: TData | undefined` - - Defaults to `undefined` - - The last successfully resolved data for the mutation. -- `error: null | TError` - - The error object for the mutation, if an error was encountered. -- `reset: () => void` - - A function to clean the mutation internal state (i.e., it resets the mutation to its initial state). -- `failureCount: number` - - The failure count for the mutation. - - Incremented every time the mutation fails. - - Reset to `0` when the mutation succeeds. -- `failureReason: null | TError` - - The failure reason for the mutation retry. - - Reset to `null` when the mutation succeeds. -- `submittedAt: number` - - The timestamp for when the mutation was submitted. - - Defaults to `0`. -- `variables: undefined | TVariables` - - The `variables` object passed to the `mutationFn`. - - Defaults to `undefined`. diff --git a/docs/framework/solid/reference/useMutationState.md b/docs/framework/solid/reference/useMutationState.md deleted file mode 100644 index c0dbe13af9..0000000000 --- a/docs/framework/solid/reference/useMutationState.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -id: useMutationState -title: useMutationState ---- - -`useMutationState` is a hook that gives you access to all mutations in the `MutationCache`. You can pass `filters` to it to narrow down your mutations, and `select` to transform the mutation state. - -**Example 1: Get all variables of all running mutations** - -```tsx -import { useMutationState } from '@tanstack/solid-query' - -const variables = useMutationState(() => ({ - filters: { status: 'pending' }, - select: (mutation) => mutation.state.variables, -})) - -// Access the current variables -variables() -``` - -**Example 2: Get all data for specific mutations via the `mutationKey`** - -```tsx -import { useMutation, useMutationState } from '@tanstack/solid-query' - -const mutationKey = ['posts'] - -// Some mutation that we want to get the state for -const mutation = useMutation(() => ({ - mutationKey, - mutationFn: (newPost) => { - return axios.post('/posts', newPost) - }, -})) - -const data = useMutationState(() => ({ - // this mutation key needs to match the mutation key of the given mutation (see above) - filters: { mutationKey }, - select: (mutation) => mutation.state.data, -})) -``` - -**Example 3: Access the latest mutation data via the `mutationKey`**. -Each invocation of `mutate` adds a new entry to the mutation cache for `gcTime` milliseconds. - -To access the latest invocation, you can check for the last item that `useMutationState` returns. - -```tsx -import { useMutation, useMutationState } from '@tanstack/solid-query' - -const mutationKey = ['posts'] - -// Some mutation that we want to get the state for -const mutation = useMutation(() => ({ - mutationKey, - mutationFn: (newPost) => { - return axios.post('/posts', newPost) - }, -})) - -const data = useMutationState(() => ({ - // this mutation key needs to match the mutation key of the given mutation (see above) - filters: { mutationKey }, - select: (mutation) => mutation.state.data, -})) - -// Latest mutation data -const latest = data()[data().length - 1] -``` - -**Options** - -- `options` - - `filters?: MutationFilters`: [Mutation Filters](../guides/filters.md#mutation-filters) - - `select?: (mutation: Mutation) => TResult` - - Use this to transform the mutation state. -- `queryClient?: Accessor` - - Use this to use a custom QueryClient. Otherwise, the one from the nearest context will be used. - -**Returns** - -- `Accessor>` - - Will resolve to an Array of whatever `select` returns for each matching mutation. diff --git a/docs/framework/solid/reference/useQueries.md b/docs/framework/solid/reference/useQueries.md deleted file mode 100644 index 0dd688de8f..0000000000 --- a/docs/framework/solid/reference/useQueries.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -id: useQueries -title: useQueries ---- - -The `useQueries` hook can be used to fetch a variable number of queries: - -```tsx -const ids = [1, 2, 3] -const results = useQueries(() => ({ - queries: ids.map((id) => ({ - queryKey: ['post', id], - queryFn: () => fetchPost(id), - staleTime: Infinity, - })), -})) -``` - -**Options** - -The `useQueries` hook accepts an options object with a **queries** key whose value is an array with query option objects identical to the [`useQuery` hook](./useQuery.md) (excluding the `queryClient` option - because the `QueryClient` can be passed in on the top level). - -- `queryClient?: QueryClient` - - Use this to provide a custom QueryClient. Otherwise, the one from the nearest context will be used. -- `combine?: (result: UseQueriesResults) => TCombinedResult` - - Use this to combine the results of the queries into a single value. - -> 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. - -**placeholderData** - -The `placeholderData` option exists for `useQueries` as well, but it doesn't get information passed from previously rendered Queries like `useQuery` does, because the input to `useQueries` can be a different number of Queries on each render. - -**Returns** - -The `useQueries` hook returns an array with all the query results. The order returned is the same as the input order. - -## Combine - -If you want to combine `data` (or other Query information) from the results into a single value, you can use the `combine` option. The result will be structurally shared to be as referentially stable as possible. - -```tsx -const ids = [1, 2, 3] -const combinedQueries = useQueries(() => ({ - queries: ids.map((id) => ({ - queryKey: ['post', id], - queryFn: () => fetchPost(id), - })), - combine: (results) => { - return { - data: results.map((result) => result.data), - pending: results.some((result) => result.isPending), - } - }, -})) -``` - -In the above example, `combinedQueries` will be an object with a `data` and a `pending` property. Note that all other properties of the Query results will be lost. - -### Memoization - -The `combine` function will only re-run if: - -- the `combine` function itself changed referentially -- any of the query results changed - -This means that an inlined `combine` function, as shown above, gets a new reference every time the options accessor re-evaluates. To avoid this, define `combine` as a stable function outside the accessor. - -## TypeScript: typing the `select` option - -Unlike `useQuery`, `useQueries` cannot infer the `data` argument of an _inline_ `select` from its sibling `queryFn`. Because `useQueries` infers the type of the whole `queries` array at once, the `select` parameter of a query object written inline cannot be contextually typed from that same object's `queryFn`, so it falls back to `unknown`. This is a [known TypeScript limitation](https://github.com/TanStack/query/issues/6556). - -```tsx -useQueries(() => ({ - queries: [ - { - queryKey: ['post', 1], - queryFn: () => fetchPost(1), - // ❌ `data` is `unknown` here - select: (data) => data.title, - }, - ], -})) -``` - -There are two supported workarounds: - -1. Annotate the `select` parameter explicitly: - -```tsx -useQueries(() => ({ - queries: [ - { - queryKey: ['post', 1], - queryFn: () => fetchPost(1), - // ✅ `data` is `Post` - select: (data: Post) => data.title, - }, - ], -})) -``` - -2. Define the query with the [`queryOptions`](./queryOptions.md) helper, which resolves its types in a single object _before_ it reaches `useQueries`: - -```tsx -const postOptions = (id: number) => - queryOptions({ - queryKey: ['post', id], - queryFn: () => fetchPost(id), - // ✅ `data` is `Post` - select: (data) => data.title, - }) - -useQueries(() => ({ queries: [postOptions(1), postOptions(2)] })) -``` - -The same limitation applies when you spread a `queryOptions` result to override its `select` inline — the overriding `select` still falls back to `unknown`: - -```tsx -useQueries(() => ({ - queries: [ - { - ...postOptions(1), - // ❌ `data` is `unknown` here - select: (data) => data.title, - }, - ], -})) -``` - -Wrap the spread in `queryOptions` again so the override is resolved before it reaches `useQueries`: - -```tsx -useQueries(() => ({ - queries: [ - queryOptions({ - ...postOptions(1), - // ✅ `data` is `Post` - select: (data) => data.title, - }), - ], -})) -``` diff --git a/docs/framework/solid/reference/useQuery.md b/docs/framework/solid/reference/useQuery.md deleted file mode 100644 index 3e3378cb3e..0000000000 --- a/docs/framework/solid/reference/useQuery.md +++ /dev/null @@ -1,379 +0,0 @@ ---- -id: useQuery -title: useQuery ---- - -```tsx -const { - data, - dataUpdatedAt, - error, - errorUpdateCount, - errorUpdatedAt, - failureCount, - failureReason, - fetchStatus, - isError, - isFetched, - isFetchedAfterMount, - isFetching, - isInitialLoading, - isLoading, - isLoadingError, - isPaused, - isPending, - isPlaceholderData, - isRefetchError, - isRefetching, - isStale, - isSuccess, - refetch, - status, -} = useQuery( - () => ({ - queryKey, - queryFn, - enabled, - select, - placeholderData, - deferStream, - reconcile, - gcTime, - networkMode, - initialData, - initialDataUpdatedAt, - meta, - queryKeyHashFn, - refetchInterval, - refetchIntervalInBackground, - refetchOnMount, - refetchOnReconnect, - refetchOnWindowFocus, - retry, - retryOnMount, - retryDelay, - staleTime, - throwOnError, - }), - () => queryClient, -) -``` - -## Usage example - -Here are some examples of how to use the `useQuery` primitive in Solid Query. - -### Basic - -The most basic usage of `useQuery` is to create a query that fetches data from an API. - -```tsx -import { useQuery } from '@tanstack/solid-query' - -function App() { - const todos = useQuery(() => ({ - queryKey: 'todos', - queryFn: async () => { - const response = await fetch('/api/todos') - if (!response.ok) { - throw new Error('Failed to fetch todos') - } - return response.json() - }, - })) - - return ( -
    - -
    Error: {todos.error.message}
    -
    - -
    Loading...
    -
    - -
    -
    Todos:
    -
      - {(todo) =>
    • {todo.title}
    • }
      -
    -
    -
    -
    - ) -} -``` - -### Reactive Options - -The reason why `useQuery` accepts a function that returns an object is to allow for reactive options. This is useful when query options depend on other values/signals that might change over time. Solid Query can track the passed function in a reactive scope and re-run it whenever the dependencies change. - -```tsx -import { useQuery } from '@tanstack/solid-query' - -function App() { - const [filter, setFilter] = createSignal('all') - - const todos = useQuery(() => ({ - queryKey: ['todos', filter()], - queryFn: async () => { - const response = await fetch(`/api/todos?filter=${filter()}`) - if (!response.ok) { - throw new Error('Failed to fetch todos') - } - return response.json() - }, - })) - - return ( -
    -
    - - - -
    - -
    Error: {todos.error.message}
    -
    - -
    Loading...
    -
    - -
    -
    Todos:
    -
      - {(todo) =>
    • {todo.title}
    • }
      -
    -
    -
    -
    - ) -} -``` - -### Usage with `Suspense` - -`useQuery` supports triggering SolidJS `Suspense` and `ErrorBoundary` components when the query is in a pending or error state. This allows you to easily handle loading and error states in your components. - -```tsx -import { useQuery } from '@tanstack/solid-query' - -function App() { - const todos = useQuery(() => ({ - queryKey: 'todos', - queryFn: async () => { - const response = await fetch('/api/todos') - if (!response.ok) { - throw new Error('Failed to fetch todos') - } - return response.json() - }, - throwOnError: true, - })) - - return ( - Error: {todos.error.message}}> - Loading...}> -
    -
    Todos:
    -
      - {(todo) =>
    • {todo.title}
    • }
      -
    -
    -
    -
    - ) -} -``` - -## `useQuery` Parameters - -- ### Query Options - `Accessor` - - ##### `queryKey: unknown[]` - - **Required** - - The query key to use for this query. - - The query key will be hashed into a stable hash. See [Query Keys](../guides/query-keys.md) for more information. - - The query will automatically update when this key changes (as long as `enabled` is not set to `false`). - - ##### `queryFn: (context: QueryFunctionContext) => Promise` - - **Required, but only if no default query function has been defined** See [Default Query Function](../guides/default-query-function.md) for more information. - - The function that the query will use to request data. - - Receives a [QueryFunctionContext](../guides/query-functions.md#queryfunctioncontext) - - Must return a promise that will either resolve data or throw an error. The data cannot be `undefined`. - - ##### `enabled: boolean` - - Set this to `false` to disable this query from automatically running. - - Can be used for [Dependent Queries](../guides/dependent-queries.md) for more information. - - ##### `select: (data: TData) => unknown` - - Optional - - This option can be used to transform or select a part of the data returned by the query function. It affects the returned `data` value, but does not affect what gets stored in the query cache. - - The `select` function will only run if `data` changed, or if the reference to the `select` function itself changes. To optimize, wrap the function in `useCallback`. - - ##### `placeholderData: TData | (previousValue: TData | undefined; previousQuery: Query | undefined,) => TData` - - Optional - - If set, this value will be used as the placeholder data for this particular query observer while the query is still in the `pending` state. - - `placeholderData` is **not persisted** to the cache - - If you provide a function for `placeholderData`, as a first argument you will receive previously watched query data if available, and the second argument will be the complete previousQuery instance. - - ##### `deferStream: boolean` - - Optional - - Defaults to `false` - - Only applicable while rendering queries on the server with streaming. - - Set `deferStream` to `true` to wait for the query to resolve on the server before flushing the stream. - - This can be useful to avoid sending a loading state to the client before the query has resolved. - - ##### `reconcile: false | string | ((oldData: TData | undefined, newData: TData) => TData)` - - Optional - - Defaults to `false` - - Set this to a string to enable reconciliation between query results based on the string key. - - Set this to a function which accepts the old and new data and returns resolved data of the same type to implement custom reconciliation logic. - - ##### `gcTime: number | Infinity` - - Defaults to `5 * 60 * 1000` (5 minutes) or `Infinity` during SSR - - The time in milliseconds that unused/inactive cache data remains in memory. When a query's cache becomes unused or inactive, that cache data will be garbage collected after this duration. When different garbage collection times are specified, the longest one will be used. - - Note: the maximum allowed time is about [24 days](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value), although it is possible to work around this limit using [timeoutManager.setTimeoutProvider](../../../reference/timeoutManager.md#timeoutmanagersettimeoutprovider). - - If set to `Infinity`, will disable garbage collection - - ##### `networkMode: 'online' | 'always' | 'offlineFirst'` - - optional - - defaults to `'online'` - - see [Network Mode](../guides/network-mode.md) for more information. - - ##### `initialData: TData | () => TData` - - Optional - - If set, this value will be used as the initial data for the query cache (as long as the query hasn't been created or cached yet) - - If set to a function, the function will be called **once** during the shared/root query initialization, and be expected to synchronously return the initialData - - Initial data is considered stale by default unless a `staleTime` has been set. - - `initialData` **is persisted** to the cache - - ##### `initialDataUpdatedAt: number | (() => number | undefined)` - - Optional - - If set, this value will be used as the time (in milliseconds) of when the `initialData` itself was last updated. - - ##### `meta: Record` - - Optional - - If set, stores additional information on the query cache entry that can be used as needed. It will be accessible wherever the `query` is available, and is also part of the `QueryFunctionContext` provided to the `queryFn`. - - ##### `queryKeyHashFn: (queryKey: QueryKey) => string` - - Optional - - If specified, this function is used to hash the `queryKey` to a string. - - ##### `refetchInterval: number | false | ((query: Query) => number | false | undefined)` - - Optional - - If set to a number, all queries will continuously refetch at this frequency in milliseconds - - If set to a function, the function will be executed with the query to compute a frequency - - ##### `refetchIntervalInBackground: boolean` - - Optional - - If set to `true`, queries that are set to continuously refetch with a `refetchInterval` will continue to refetch while their tab/window is in the background - - ##### `refetchOnMount: boolean | "always" | ((query: Query) => boolean | "always")` - - Optional - - Defaults to `true` - - If set to `true`, the query will refetch on mount if the data is stale. - - If set to `false`, the query will not refetch on mount. - - If set to `"always"`, the query will always refetch on mount. - - If set to a function, the function will be executed with the query to compute the value - - ##### `refetchOnWindowFocus: boolean | "always" | ((query: Query) => boolean | "always")` - - Optional - - Defaults to `true` - - If set to `true`, the query will refetch on window focus if the data is stale. - - If set to `false`, the query will not refetch on window focus. - - If set to `"always"`, the query will always refetch on window focus. - - If set to a function, the function will be executed with the query to compute the value - - ##### `refetchOnReconnect: boolean | "always" | ((query: Query) => boolean | "always")` - - Optional - - Defaults to `true` - - If set to `true`, the query will refetch on reconnect if the data is stale. - - If set to `false`, the query will not refetch on reconnect. - - If set to `"always"`, the query will always refetch on reconnect. - - If set to a function, the function will be executed with the query to compute the value - - ##### `retry: boolean | number | (failureCount: number, error: TError) => boolean` - - If `false`, failed queries will not retry by default. - - If `true`, failed queries will retry infinitely. - - If set to a `number`, e.g. `3`, failed queries will retry until the failed query count meets that number. - - defaults to `3` on the client and `0` on the server - - ##### `retryOnMount: boolean | (query: Query) => boolean` - - If set to `false`, the query will not be retried on mount if it contains an error and has no data. Defaults to `true`. - - If set to a function, the function will be executed with the query to compute the value. - - ##### `retryDelay: number | (retryAttempt: number, error: TError) => number` - - This function receives a `retryAttempt` integer and the actual Error and returns the delay to apply before the next attempt in milliseconds. - - A function like `attempt => Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 30 * 1000)` applies exponential backoff. - - A function like `attempt => attempt * 1000` applies linear backoff. - - ##### `staleTime: number | Infinity` - - Optional - - Defaults to `0` - - The time in milliseconds after data is considered stale. This value only applies to the hook it is defined on. - - If set to `Infinity`, the data will never be considered stale - - ##### `throwOnError: undefined | boolean | (error: TError, query: Query) => boolean` - - Optional - - Defaults to `false` - - During SSR, defaults to `true` - - If the deprecated `suspense` option is set to `true`, defaults to `true` - - Set this to `true` if you want errors to be thrown in the render phase and propagate to the nearest error boundary - - Set this to `false` to disable `suspense`'s default behavior of throwing errors to the error boundary. - - If set to a function, it will be passed the error and the query, and it should return a boolean indicating whether to show the error in an error boundary (`true`) or return the error as state (`false`) - -- ### Query Client - `Accessor` - - Optional - - Use this to use a custom QueryClient. Otherwise, the one from the nearest context will be used. - -## `useQuery` Return Value - `Store>` - -`useQuery` returns a SolidJS store with the following properties: - -- ##### `status: QueryStatus` - - Will be: - - `pending` if there's no cached data and no query attempt was finished yet. - - `error` if the query attempt resulted in an error. The corresponding `error` property has the error received from the attempted fetch - - `success` if the query has received a response with no errors and is ready to display its data. The corresponding `data` property on the query is the data received from the successful fetch or if the query's `enabled` property is set to `false` and has not been fetched yet `data` is the first `initialData` supplied to the query on initialization. -- ##### `isPending: boolean` - - A derived boolean from the `status` variable above, provided for convenience. -- ##### `isSuccess: boolean` - - A derived boolean from the `status` variable above, provided for convenience. -- ##### `isError: boolean` - - A derived boolean from the `status` variable above, provided for convenience. -- ##### `isLoadingError: boolean` - - Will be `true` if the query failed while fetching for the first time. -- ##### `isRefetchError: boolean` - - Will be `true` if the query failed while refetching. -- ##### `data: Resource` - - Defaults to `undefined`. - - The last successfully resolved data for the query. - - **Important**: The `data` property is a SolidJS resource. This means that if the data is accessed underneath a `` component, - it will trigger the Suspense boundary if the data is not available yet. -- ##### `dataUpdatedAt: number` - - The timestamp for when the query most recently returned the `status` as `"success"`. -- ##### `error: null | TError` - - Defaults to `null` - - The error object for the query, if an error was thrown. -- ##### `errorUpdatedAt: number` - - The timestamp for when the query most recently returned the `status` as `"error"`. -- ##### `isStale: boolean` - - Will be `true` if the data in the cache is invalidated or if the data is older than the given `staleTime`. -- ##### `isPlaceholderData: boolean` - - Will be `true` if the data shown is the placeholder data. -- ##### `isFetched: boolean` - - Will be `true` if the query has been fetched. -- ##### `isFetchedAfterMount: boolean` - - Will be `true` if the query has been fetched after the component mounted. - - This property can be used to not show any previously cached data. -- ##### `fetchStatus: FetchStatus` - - `fetching`: Is `true` whenever the queryFn is executing, which includes initial `pending` as well as background refetches. - - `paused`: The query wanted to fetch, but has been `paused`. - - `idle`: The query is not fetching. - - see [Network Mode](../guides/network-mode.md) for more information. -- ##### `isFetching: boolean` - - A derived boolean from the `fetchStatus` variable above, provided for convenience. -- ##### `isPaused: boolean` - - A derived boolean from the `fetchStatus` variable above, provided for convenience. -- ##### `isRefetching: boolean` - - Is `true` whenever a background refetch is in-flight, which _does not_ include initial `pending` - - Is the same as `isFetching && !isPending` -- ##### `isLoading: boolean` - - Is `true` whenever the first fetch for a query is in-flight - - Is the same as `isFetching && isPending` -- ##### `isInitialLoading: boolean` - - **deprecated** - - An alias for `isLoading`, will be removed in the next major version. -- ##### `failureCount: number` - - The failure count for the query. - - Incremented every time the query fails. - - Reset to `0` when the query succeeds. -- ##### `failureReason: null | TError` - - The failure reason for the query retry. - - Reset to `null` when the query succeeds. -- ##### `errorUpdateCount: number` - - The sum of all errors. -- ##### `refetch: (options: { throwOnError: boolean, cancelRefetch: boolean }) => Promise` - - A function to manually refetch the query. - - If the query errors, the error will only be logged. If you want an error to be thrown, pass the `throwOnError: true` option - - `cancelRefetch?: boolean` - - Defaults to `true` - - Per default, a currently running request will be cancelled before a new request is made - - When set to `false`, no refetch will be made if there is already a request running. diff --git a/docs/framework/solid/reference/variables/IsRestoringProvider.md b/docs/framework/solid/reference/variables/IsRestoringProvider.md new file mode 100644 index 0000000000..99fd1f1b78 --- /dev/null +++ b/docs/framework/solid/reference/variables/IsRestoringProvider.md @@ -0,0 +1,13 @@ +--- +id: IsRestoringProvider +title: IsRestoringProvider +--- + +```ts +const IsRestoringProvider: ContextProviderComponent> = IsRestoringContext.Provider; +``` + +Defined in: [isRestoring.ts:19](https://github.com/TanStack/query/blob/main/packages/solid-query/src/isRestoring.ts#L19) + +The Provider that `PersistQueryClientProvider` uses to signal whether a persisted client is currently +being restored, read by `useIsRestoring`. diff --git a/docs/framework/solid/reference/variables/QueryClientContext.md b/docs/framework/solid/reference/variables/QueryClientContext.md new file mode 100644 index 0000000000..b8883f1e9f --- /dev/null +++ b/docs/framework/solid/reference/variables/QueryClientContext.md @@ -0,0 +1,12 @@ +--- +id: QueryClientContext +title: QueryClientContext +--- + +```ts +const QueryClientContext: Context<() => QueryClient | undefined>; +``` + +Defined in: [QueryClientProvider.tsx:13](https://github.com/TanStack/query/blob/main/packages/solid-query/src/QueryClientProvider.tsx#L13) + +The context that `useQueryClient` reads from. `QueryClientProvider` is the normal way to set it. diff --git a/docs/framework/solid/reference/variables/createInfiniteQuery.md b/docs/framework/solid/reference/variables/createInfiniteQuery.md new file mode 100644 index 0000000000..1b388183d4 --- /dev/null +++ b/docs/framework/solid/reference/variables/createInfiniteQuery.md @@ -0,0 +1,262 @@ +--- +id: createInfiniteQuery +title: createInfiniteQuery +--- + +```ts +const createInfiniteQuery: { + (options, queryClient?): DefinedUseInfiniteQueryResult; + (options, queryClient?): UseInfiniteQueryResult; +} = useInfiniteQuery; +``` + +Defined in: [index.ts:72](https://github.com/TanStack/query/blob/main/packages/solid-query/src/index.ts#L72) + +## Call Signature + +```ts +(options, queryClient?): DefinedUseInfiniteQueryResult; +``` + +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`\<`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` 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](../functions/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 ( +
    + {projectsQuery.isError ? Error: {projectsQuery.error.message} : null} +
      + + {(page) => {(p) =>
    • {p.name}
    • }
      } +
      +
    +
    + ) +} +``` + +## Call Signature + +```ts +(options, queryClient?): UseInfiniteQueryResult; +``` + +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`\<`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` 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](../functions/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 ( + + Loading... + Error: {projectsQuery.error.message} + +
      + + {(page) => {(p) =>
    • {p.name}
    • }
      } +
      +
    + +
    +
    + ) +} +``` + +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 ( + + Loading... + Error: {projectsQuery.error.message} + +
      + + {(page) => {(p) =>
    • {p.name}
    • }
      } +
      +
    +
    {projectsQuery.isFetchingNextPage ? 'Loading more...' : null}
    +
    +
    + ) +} +``` diff --git a/docs/framework/solid/reference/variables/createMutation.md b/docs/framework/solid/reference/variables/createMutation.md new file mode 100644 index 0000000000..ff5b75419e --- /dev/null +++ b/docs/framework/solid/reference/variables/createMutation.md @@ -0,0 +1,76 @@ +--- +id: createMutation +title: createMutation +--- + +```ts +const createMutation: (options, queryClient?) => UseMutationResult = useMutation; +``` + +Defined in: [index.ts:80](https://github.com/TanStack/query/blob/main/packages/solid-query/src/index.ts#L80) + +## 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. + +## Example + +```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 ( + + ) +} +``` diff --git a/docs/framework/solid/reference/variables/createQueries.md b/docs/framework/solid/reference/variables/createQueries.md new file mode 100644 index 0000000000..e814100d77 --- /dev/null +++ b/docs/framework/solid/reference/variables/createQueries.md @@ -0,0 +1,153 @@ +--- +id: createQueries +title: createQueries +--- + +```ts +const createQueries: (queriesOptions, queryClient?) => TCombinedResult = useQueries; +``` + +Defined in: [index.ts:86](https://github.com/TanStack/query/blob/main/packages/solid-query/src/index.ts#L86) + +The `useQueries` hook can be used to fetch a variable number of queries. + +The `queries` key accepts an array with query option objects identical to `useQuery`. 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`\<`unknown`, `Error`\> + \| `QueryObserverSuccessResult`\<`unknown`, `Error`\> + \| `QueryObserverLoadingErrorResult`\<`unknown`, `Error`\> + \| `QueryObserverLoadingResult`\<`unknown`, `Error`\> + \| `QueryObserverPendingResult`\<`unknown`, `Error`\> + \| `QueryObserverPlaceholderResult`\<`unknown`, `Error`\> + \| `QueryObserverRefetchErrorResult`\<`unknown`, `unknown`\> + \| `QueryObserverSuccessResult`\<`unknown`, `unknown`\> + \| `QueryObserverLoadingErrorResult`\<`unknown`, `unknown`\> + \| `QueryObserverLoadingResult`\<`unknown`, `unknown`\> + \| `QueryObserverPendingResult`\<`unknown`, `unknown`\> + \| `QueryObserverPlaceholderResult`\<`unknown`, `unknown`\>\] + \| ( + \| `QueryObserverRefetchErrorResult`\<`unknown`, `Error`\> + \| `QueryObserverSuccessResult`\<`unknown`, `Error`\> + \| `QueryObserverLoadingErrorResult`\<`unknown`, `Error`\> + \| `QueryObserverLoadingResult`\<`unknown`, `Error`\> + \| `QueryObserverPendingResult`\<`unknown`, `Error`\> + \| `QueryObserverPlaceholderResult`\<`unknown`, `Error`\> + \| `QueryObserverRefetchErrorResult`\<`unknown`, `unknown`\> + \| `QueryObserverSuccessResult`\<`unknown`, `unknown`\> + \| `QueryObserverLoadingErrorResult`\<`unknown`, `unknown`\> + \| `QueryObserverLoadingResult`\<`unknown`, `unknown`\> + \| `QueryObserverPendingResult`\<`unknown`, `unknown`\> + \| `QueryObserverPlaceholderResult`\<`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`\<...\>, `GetResults`\<...\>, `GetResults`\<...\>\] : \[`...(...)[]`\] *extends* \[..., `...(...)[]`\] ? ... *extends* ... ? ... : ... : \[`...(...)[]`\] : \[...\{ \[K in string \| number \| symbol\]: GetResults\<(...)\[(...)\]\> \}\[\]\] : \{ \[K in string \| number \| symbol\]: GetResults\\]\> \} + +## Parameters + +### queriesOptions + +`Accessor`\<\{ + `combine?`: (`result`) => `TCombinedResult`; + `queries`: \| readonly \[`T` *extends* \[\] ? \[\] : `T` *extends* \[`Head`\] ? \[`GetOptions`\<`Head`\>\] : `T` *extends* \[`Head`, `...Tail[]`\] ? \[`...Tail[]`\] *extends* \[\] ? \[\] : \[`...(...)[]`\] *extends* \[...\] ? \[..., ...\] : ... *extends* ... ? ... : ... : readonly `unknown`[] *extends* `T` ? `T` : `T` *extends* ...[] ? ...[] : ...[]\] + \| readonly \[\{ \[K in string \| number \| symbol\]: GetOptions\\]\> \}\]; +\}\> + +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 }) { + const postQueries = useQueries(() => ({ + queries: props.ids.map((id) => ({ + queryKey: ['post', id], + queryFn: () => fetchPost(id), + staleTime: Infinity, + })), + })) + + return ( +
      + + {(postQuery) => { + if (postQuery.isPending) return
    • Loading...
    • + if (postQuery.isError) return
    • Error: {postQuery.error.message}
    • + return
    • {postQuery.data.title}
    • + }} +
      +
    + ) +} +``` + +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 }) { + 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 ( + + {(post) =>
  • {post?.title}
  • }
    + + } + > + Loading... + Error loading posts +
    + ) +} +``` diff --git a/docs/framework/solid/reference/variables/createQuery.md b/docs/framework/solid/reference/variables/createQuery.md new file mode 100644 index 0000000000..3f0810f24a --- /dev/null +++ b/docs/framework/solid/reference/variables/createQuery.md @@ -0,0 +1,293 @@ +--- +id: createQuery +title: createQuery +--- + +```ts +const createQuery: { + (options, queryClient?): UseQueryResult; + (options, queryClient?): DefinedUseQueryResult; +} = useQuery; +``` + +Defined in: [index.ts:57](https://github.com/TanStack/query/blob/main/packages/solid-query/src/index.ts#L57) + +## Call Signature + +```ts +(options, queryClient?): UseQueryResult; +``` + +### 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](../functions/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 ( + + Loading... + Error: {postsQuery.error.message} + +
      + {(post) =>
    • {post.title}
    • }
      +
    +
    {postsQuery.isFetching ? 'Background Updating...' : ' '}
    +
    +
    + ) +} +``` + +`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 ( + + Loading... + Error: {postsQuery.error.message} + {postsQuery.data} posts + + ) +} +``` + +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 ( + {postQuery.data?.title}}> + Select a post + Loading... + Error: {postQuery.error.message} + + ) +} +``` + +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 ( + {postQuery.data?.title}}> + Select a post + Loading... + Error: {postQuery.error.message} + + ) +} +``` + +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>(['posts']) + ?.find((post) => post.id === props.postId), + })) + + return postQuery.isError ? Error: {postQuery.error.message} :

    {postQuery.data?.title}

    +} +``` + +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 ( +
    +
      + {(post) =>
    • {post.title}
    • }
      +
    + +
    + ) +} +``` + +## Call Signature + +```ts +(options, queryClient?): DefinedUseQueryResult; +``` + +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](../functions/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 ( +
    + {postsQuery.isError ? Error: {postsQuery.error.message} : null} +
      + {(post) =>
    • {post.title}
    • }
      +
    +
    + ) +} +``` diff --git a/docs/framework/solid/typescript.md b/docs/framework/solid/typescript.md index 9ea7485af9..e6ba3c0897 100644 --- a/docs/framework/solid/typescript.md +++ b/docs/framework/solid/typescript.md @@ -154,7 +154,7 @@ query.error ## Registering global `Meta` -Similarly to registering a [global error type](#registering-a-global-error) you can also register a global `Meta` type. This ensures the optional `meta` field on [queries](./reference/useQuery.md) and [mutations](./reference/useMutation.md) stays consistent and is type-safe. Note that the registered type must extend `Record` so that `meta` remains an object. +Similarly to registering a [global error type](#registering-a-global-error) you can also register a global `Meta` type. This ensures the optional `meta` field on [queries](./reference/functions/useQuery.md) and [mutations](./reference/functions/useMutation.md) stays consistent and is type-safe. Note that the registered type must extend `Record` so that `meta` remains an object. ```ts import '@tanstack/solid-query' diff --git a/packages/solid-query/src/QueryClient.ts b/packages/solid-query/src/QueryClient.ts index 998c92b808..f3300ae68f 100644 --- a/packages/solid-query/src/QueryClient.ts +++ b/packages/solid-query/src/QueryClient.ts @@ -9,6 +9,17 @@ import type { QueryKey, } from '@tanstack/query-core' +/** + * The core `QueryObserverOptions`, with Solid's `reconcile` option added. + * + * @template TQueryFnData - The type your `queryFn` resolves to. + * @template TError - The type of errors your `queryFn` may throw. + * @template TData - The type `data` ends up as after `select` runs. + * @template TQueryData - The type of the data actually held in the query cache. + * @template TQueryKey - The type of your `queryKey`. + * @template TPageParam - The type of the parameter passed to `queryFn` to fetch a given page, when this type + * is shared with an infinite query's observer options. Defaults to `never` for regular queries. + */ export interface QueryObserverOptions< TQueryFnData = unknown, TError = DefaultError, @@ -39,6 +50,15 @@ export interface QueryObserverOptions< | ((oldData: TData | undefined, newData: TData) => TData) } +/** + * The core `InfiniteQueryObserverOptions`, with Solid's `reconcile` option added. + * + * @template TQueryFnData - The type of a single page, as your `queryFn` resolves it. + * @template TError - The type of errors your `queryFn` may throw. + * @template TData - The type `data` ends up as after `select` runs. + * @template TQueryKey - The type of your `queryKey`. + * @template TPageParam - The type of the parameter passed to `queryFn` to fetch a given page. + */ export interface InfiniteQueryObserverOptions< TQueryFnData = unknown, TError = DefaultError, @@ -67,16 +87,29 @@ export interface InfiniteQueryObserverOptions< | ((oldData: TData | undefined, newData: TData) => TData) } +/** + * The default options a `QueryClient` applies to every query, with Solid's `reconcile` option added to + * `queries`. + * + * @template TError - The default type of errors thrown by queries and mutations using this `QueryClient`. + */ export interface DefaultOptions< TError = DefaultError, > extends CoreDefaultOptions { queries?: OmitKeyof, 'queryKey'> } +/** + * The config accepted by `new QueryClient(config)`, with Solid's extended {@link DefaultOptions}. + */ export interface QueryClientConfig extends QueryCoreClientConfig { defaultOptions?: DefaultOptions } +/** + * The core `@tanstack/query-core` `QueryClient`, typed so its `defaultOptions.queries` accepts Solid's + * `reconcile` option. + */ export class QueryClient extends QueryCoreClient { constructor(config: QueryClientConfig = {}) { super(config) diff --git a/packages/solid-query/src/QueryClientProvider.tsx b/packages/solid-query/src/QueryClientProvider.tsx index fb461c9eaf..ec004c0237 100644 --- a/packages/solid-query/src/QueryClientProvider.tsx +++ b/packages/solid-query/src/QueryClientProvider.tsx @@ -7,6 +7,9 @@ import { import type { QueryClient } from './QueryClient' import type { Accessor, JSX } from 'solid-js' +/** + * The context that `useQueryClient` reads from. `QueryClientProvider` is the normal way to set it. + */ export const QueryClientContext = createContext< (() => QueryClient) | undefined >(undefined) @@ -14,6 +17,14 @@ export const QueryClientContext = createContext< const queryClientContextError = 'No QueryClient set, use QueryClientProvider to set one' +/** + * The `useQueryClient` hook returns the current `QueryClient` instance. + * + * @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will + * be used. + * @returns The current `QueryClient` instance. + * @throws If no `queryClient` argument is passed and no `QueryClientProvider` is found in the component tree. + */ export const useQueryClient = (queryClient?: QueryClient) => { if (queryClient) { return queryClient @@ -46,11 +57,41 @@ export const useQueryClientResolver = ( } } +/** + * The props accepted by `QueryClientProvider`. + */ export type QueryClientProviderProps = { + /** + * **Required** + * + * The `QueryClient` instance to provide. + */ client: QueryClient + /** + * The components that get access to the provided `QueryClient`. + */ children?: JSX.Element } +/** + * 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). + * + * @returns 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 ... + * } + * ``` + */ export const QueryClientProvider = ( props: QueryClientProviderProps, ): JSX.Element => { diff --git a/packages/solid-query/src/infiniteQueryOptions.ts b/packages/solid-query/src/infiniteQueryOptions.ts index 1648882d2f..5ff531c766 100644 --- a/packages/solid-query/src/infiniteQueryOptions.ts +++ b/packages/solid-query/src/infiniteQueryOptions.ts @@ -8,6 +8,20 @@ import type { import type { InfiniteQueryOptions } from './types' import type { Accessor } from 'solid-js' +/** + * The options accepted by the `infiniteQueryOptions` overload selected when no `initialData` is set — `data` + * may be `undefined` while the query is `pending`. `infiniteQueryOptions` itself accepts and returns a plain + * object (its parameter type is `ReturnType>`, i.e. this `Accessor` + * called); Solid's reactivity applies where the result is consumed instead, e.g. + * `useInfiniteQuery(() => options)`. + * + * @template TQueryFnData - The type of a single page, as your `queryFn` resolves it. + * @template TError - The type of errors your `queryFn` may throw. + * @template TData - The type `data` ends up as after `select` runs — defaults to `InfiniteData`, + * the shape of all fetched pages plus their page params. + * @template TQueryKey - The type of your `queryKey`. + * @template TPageParam - The type of the parameter passed to `queryFn` to fetch a given page. + */ export type UndefinedInitialDataInfiniteOptions< TQueryFnData, TError = DefaultError, @@ -20,6 +34,17 @@ export type UndefinedInitialDataInfiniteOptions< } > +/** + * The options accepted by the `infiniteQueryOptions` overload selected when `initialData` is set — `data` is + * never `undefined`. + * + * @template TQueryFnData - The type of a single page, as your `queryFn` resolves it. + * @template TError - The type of errors your `queryFn` may throw. + * @template TData - The type `data` ends up as after `select` runs — defaults to `InfiniteData`, + * the shape of all fetched pages plus their page params. + * @template TQueryKey - The type of your `queryKey`. + * @template TPageParam - The type of the parameter passed to `queryFn` to fetch a given page. + */ export type DefinedInitialDataInfiniteOptions< TQueryFnData, TError = DefaultError, @@ -34,6 +59,49 @@ export type DefinedInitialDataInfiniteOptions< | (() => NonUndefinedGuard>) } > + +/** + * 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. + * + * @see {@link useInfiniteQuery} to run an infinite query with these options. + * @param options - The {@link DefinedInitialDataInfiniteOptions} to use — everything you can pass to `useInfiniteQuery`, with `initialData` set. + * @returns The same options object, typed so that `queryKey` carries the inferred data type. + * + * @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 ( + *
    + * {projectsQuery.isError ? Error: {projectsQuery.error.message} : null} + *
      + * + * {(page) => {(p) =>
    • {p.name}
    • }
      } + *
      + *
    + *
    + * ) + * } + * ``` + */ export function infiniteQueryOptions< TQueryFnData, TError = DefaultError, @@ -60,6 +128,49 @@ export function infiniteQueryOptions< > > & QueryKeyWithDataTag, TError> + +/** + * 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. + * + * @see {@link useInfiniteQuery} to run an infinite query with these options. + * @param options - The {@link UndefinedInitialDataInfiniteOptions} to use — everything you can pass to `useInfiniteQuery`. + * @returns The same options object, typed so that `queryKey` carries the inferred data type. + * + * @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 ( + * + * Loading... + * Error: {commentsQuery.error.message} + * + *
      + * + * {(page) => {(c) =>
    • {c.text}
    • }
      } + *
      + *
    + *
    + *
    + * ) + * } + * ``` + */ export function infiniteQueryOptions< TQueryFnData, TError = DefaultError, diff --git a/packages/solid-query/src/isRestoring.ts b/packages/solid-query/src/isRestoring.ts index fbeceafd02..c74b4132e7 100644 --- a/packages/solid-query/src/isRestoring.ts +++ b/packages/solid-query/src/isRestoring.ts @@ -3,5 +3,17 @@ import type { Accessor } from 'solid-js' const IsRestoringContext = createContext>(() => false) +/** + * 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 An accessor that reads `true` while a persisted client is being restored, `false` otherwise. + */ export const useIsRestoring = () => useContext(IsRestoringContext) + +/** + * The Provider that `PersistQueryClientProvider` uses to signal whether a persisted client is currently + * being restored, read by `useIsRestoring`. + */ export const IsRestoringProvider = IsRestoringContext.Provider diff --git a/packages/solid-query/src/mutationOptions.ts b/packages/solid-query/src/mutationOptions.ts index 91caa28d44..811463a273 100644 --- a/packages/solid-query/src/mutationOptions.ts +++ b/packages/solid-query/src/mutationOptions.ts @@ -1,6 +1,35 @@ import type { DefaultError, WithRequired } from '@tanstack/query-core' import type { MutationOptions } from './types' +/** + * 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`. + * + * @see {@link useMutation} to run the mutation these options describe. + * @param options - The mutation options to use, identical to what you'd pass to `useMutation`, with a + * required `mutationKey`. + * @returns The same options object, unchanged. + * + * @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 ? Saving… : null + * } + * ``` + */ export function mutationOptions< TData = unknown, TError = DefaultError, @@ -15,6 +44,32 @@ export function mutationOptions< MutationOptions, 'mutationKey' > +/** + * 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`. + * + * @see {@link useMutation} to run the mutation these options describe. + * @param options - The mutation options to use, identical to what you'd pass to `useMutation`, without a + * `mutationKey`. + * @returns The same options object, unchanged. + * @remarks 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 + * } + * ``` + */ export function mutationOptions< TData = unknown, TError = DefaultError, diff --git a/packages/solid-query/src/queryOptions.ts b/packages/solid-query/src/queryOptions.ts index 55e16871ea..22ab259c0a 100644 --- a/packages/solid-query/src/queryOptions.ts +++ b/packages/solid-query/src/queryOptions.ts @@ -6,6 +6,17 @@ import type { import type { QueryOptions } from './types' import type { Accessor } from 'solid-js' +/** + * The options accepted by the `queryOptions` overload selected when no `initialData` is set — `data` may be + * `undefined` while the query is `pending`. `queryOptions` itself accepts and returns a plain object (its + * parameter type is `ReturnType>`, i.e. this `Accessor` called); Solid's + * reactivity applies where the result is consumed instead, e.g. `useQuery(() => options)`. + * + * @template TQueryFnData - The type your `queryFn` resolves to. + * @template TError - The type of errors your `queryFn` may throw. + * @template TData - The type `data` ends up as after `select` runs. + * @template TQueryKey - The type of your `queryKey`. + */ export type UndefinedInitialDataOptions< TQueryFnData = unknown, TError = DefaultError, @@ -17,6 +28,15 @@ export type UndefinedInitialDataOptions< } > +/** + * The options accepted by the `queryOptions` overload selected when `initialData` is set — `data` is never + * `undefined`. + * + * @template TQueryFnData - The type your `queryFn` resolves to. + * @template TError - The type of errors your `queryFn` may throw. + * @template TData - The type `data` ends up as after `select` runs. + * @template TQueryKey - The type of your `queryKey`. + */ export type DefinedInitialDataOptions< TQueryFnData = unknown, TError = DefaultError, @@ -28,6 +48,45 @@ export type DefinedInitialDataOptions< } > +/** + * 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`. + * + * @see {@link useQuery} to run a query with these options. + * @see [The Query Options API](https://tkdodo.eu/blog/the-query-options-api) for more on this pattern. + * @param options - The {@link DefinedInitialDataOptions} to use — everything you can pass to `useQuery`, with `initialData` set. + * @returns The same options object, typed so that `queryKey` carries the inferred data type. + * + * @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 ( + *
    + * {postsQuery.isError ? Error: {postsQuery.error.message} : null} + *
      + * {(post) =>
    • {post.title}
    • }
      + *
    + *
    + * ) + * } + * ``` + */ export function queryOptions< TQueryFnData = unknown, TError = DefaultError, @@ -35,13 +94,50 @@ export function queryOptions< TQueryKey extends QueryKey = QueryKey, >( options: ReturnType< - UndefinedInitialDataOptions + DefinedInitialDataOptions >, ): ReturnType< - UndefinedInitialDataOptions + DefinedInitialDataOptions > & QueryKeyWithDataTag +/** + * 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. + * + * @see {@link useQuery} to run a query with these options. + * @see [The Query Options API](https://tkdodo.eu/blog/the-query-options-api) for more on this pattern. + * @param options - The {@link UndefinedInitialDataOptions} to use — everything you can pass to `useQuery`. + * @returns The same options object, typed so that `queryKey` carries the inferred data type. + * + * @example + * 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 ( + * + * Loading... + * Error: {postQuery.error.message} + * + *

    {postQuery.data.title}

    + *
    + *
    + * ) + * } + * ``` + */ export function queryOptions< TQueryFnData = unknown, TError = DefaultError, @@ -49,10 +145,10 @@ export function queryOptions< TQueryKey extends QueryKey = QueryKey, >( options: ReturnType< - DefinedInitialDataOptions + UndefinedInitialDataOptions >, ): ReturnType< - DefinedInitialDataOptions + UndefinedInitialDataOptions > & QueryKeyWithDataTag diff --git a/packages/solid-query/src/types.ts b/packages/solid-query/src/types.ts index 1c5bd10a24..0aeebe9a91 100644 --- a/packages/solid-query/src/types.ts +++ b/packages/solid-query/src/types.ts @@ -19,6 +19,18 @@ import type { } from './QueryClient' import type { Accessor } from 'solid-js' +/** + * The options accepted by `useQuery`. Extends {@link QueryObserverOptions} from `@tanstack/query-core` with + * the `solid-query`-specific `deferStream` and `suspense` options. + * + * @template TQueryFnData - The type your `queryFn` resolves to. + * @template TError - The type of errors your `queryFn` may throw. + * @template TData - The type `data` ends up as after `select` runs. Defaults to `TQueryFnData` when no + * `select` is used. + * @template TQueryData - The type of the data actually held in the query cache — the input to `select` and + * `placeholderData`. Defaults to, and is usually the same as, `TQueryFnData`. + * @template TQueryKey - The type of your `queryKey`. + */ export interface UseBaseQueryOptions< TQueryFnData = unknown, TError = DefaultError, @@ -44,6 +56,15 @@ export interface UseBaseQueryOptions< suspense?: boolean } +/** + * The options accepted by `useQuery` and `queryOptions`. + * + * @template TQueryFnData - The type your `queryFn` resolves to. + * @template TError - The type of errors your `queryFn` may throw. + * @template TData - The type `data` ends up as after `select` runs. Defaults to `TQueryFnData` when no + * `select` is used. + * @template TQueryKey - The type of your `queryKey`. + */ export interface QueryOptions< TQueryFnData = unknown, TError = DefaultError, @@ -57,6 +78,16 @@ export interface QueryOptions< TQueryKey > {} +/** + * The accessor `useQuery` expects as its first argument — Solid re-evaluates it reactively, so `queryKey` and + * other options can depend on signals. + * + * @template TQueryFnData - The type your `queryFn` resolves to. + * @template TError - The type of errors your `queryFn` may throw. + * @template TData - The type `data` ends up as after `select` runs. Defaults to `TQueryFnData` when no + * `select` is used. + * @template TQueryKey - The type of your `queryKey`. + */ export type UseQueryOptions< TQueryFnData = unknown, TError = DefaultError, @@ -66,27 +97,63 @@ export type UseQueryOptions< /* --- Create Query and Create Base Query Types --- */ +/** + * The object `useQuery` returns when `initialData` isn't set — `data`/`error` may still be `undefined`/`null` + * while the query is `pending`. Re-exports {@link QueryObserverResult} from `@tanstack/query-core`. + * `useInfiniteQuery` returns {@link UseInfiniteQueryResult} instead. + * + * @template TData - The type `data` ends up as, after `select` runs (if set). + * @template TError - The type of errors this query may hold. + */ export type UseBaseQueryResult< TData = unknown, TError = DefaultError, > = QueryObserverResult +/** + * The object `useQuery` returns — `data`/`error` may still be `undefined`/`null` while the query is + * `pending`. + * + * @template TData - The type `data` ends up as, after `select` runs (if set). + * @template TError - The type of errors this query may hold. + */ export type UseQueryResult< TData = unknown, TError = DefaultError, > = UseBaseQueryResult +/** + * The object `useQuery` returns when `initialData` guarantees `data` is never `undefined`. + * + * @template TData - The type `data` ends up as, after `select` runs (if set). + * @template TError - The type of errors this query may hold. + */ export type DefinedUseBaseQueryResult< TData = unknown, TError = DefaultError, > = DefinedQueryObserverResult +/** + * The object `useQuery` returns when `initialData` guarantees `data` is never `undefined`. + * + * @template TData - The type `data` ends up as, after `select` runs (if set). + * @template TError - The type of errors this query may hold. + */ export type DefinedUseQueryResult< TData = unknown, TError = DefaultError, > = DefinedUseBaseQueryResult /* --- Create Infinite Queries Types --- */ +/** + * The options accepted by `useInfiniteQuery`. + * + * @template TQueryFnData - The type of a single page, as your `queryFn` resolves it. + * @template TError - The type of errors your `queryFn` may throw. + * @template TData - The type `data` ends up as after `select` runs. + * @template TQueryKey - The type of your `queryKey`. + * @template TPageParam - The type of the parameter passed to `queryFn` to fetch a given page. + */ export interface InfiniteQueryOptions< TQueryFnData = unknown, TError = DefaultError, @@ -119,6 +186,16 @@ export interface InfiniteQueryOptions< suspense?: boolean } +/** + * The accessor `useInfiniteQuery` expects as its first argument — Solid re-evaluates it reactively, so + * `queryKey` and other options can depend on signals. + * + * @template TQueryFnData - The type of a single page, as your `queryFn` resolves it. + * @template TError - The type of errors your `queryFn` may throw. + * @template TData - The type `data` ends up as after `select` runs. + * @template TQueryKey - The type of your `queryKey`. + * @template TPageParam - The type of the parameter passed to `queryFn` to fetch a given page. + */ export type UseInfiniteQueryOptions< TQueryFnData = unknown, TError = DefaultError, @@ -129,17 +206,38 @@ export type UseInfiniteQueryOptions< InfiniteQueryOptions > +/** + * The object `useInfiniteQuery` returns — `data`/`error` may still be `undefined`/`null` while the query is + * `pending`. + * + * @template TData - The type `data` ends up as, after `select` runs (if set). + * @template TError - The type of errors this query may hold. + */ export type UseInfiniteQueryResult< TData = unknown, TError = DefaultError, > = InfiniteQueryObserverResult +/** + * The object `useInfiniteQuery` returns when `initialData` guarantees `data` is never `undefined`. + * + * @template TData - The type `data` ends up as, after `select` runs (if set). + * @template TError - The type of errors this query may hold. + */ export type DefinedUseInfiniteQueryResult< TData = unknown, TError = DefaultError, > = DefinedInfiniteQueryObserverResult /* --- Create Mutation Types --- */ +/** + * The options accepted by `useMutation` and `mutationOptions`. + * + * @template TData - The type your `mutationFn` resolves to. + * @template TError - The type of errors your `mutationFn` may throw. + * @template TVariables - The type of the variables your `mutationFn` accepts. + * @template TOnMutateResult - The type returned by `onMutate`, passed on to `onSuccess`/`onError`/`onSettled`. + */ export interface MutationOptions< TData = unknown, TError = DefaultError, @@ -150,6 +248,15 @@ export interface MutationOptions< '_defaulted' > {} +/** + * The accessor `useMutation` expects as its first argument — Solid re-evaluates it reactively, so callbacks + * and other options can depend on signals. + * + * @template TData - The type your `mutationFn` resolves to. + * @template TError - The type of errors your `mutationFn` may throw. + * @template TVariables - The type of the variables your `mutationFn` accepts. + * @template TOnMutateResult - The type returned by `onMutate`, passed on to `onSuccess`/`onError`/`onSettled`. + */ export type UseMutationOptions< TData = unknown, TError = DefaultError, @@ -168,6 +275,16 @@ export type UseMutateFunction< > ) => void +/** + * The type of `mutateAsync`, as returned by `useMutation`. Similar to {@link UseMutateFunction}, but returns a + * promise which can be awaited. + * + * @template TData - The type your `mutationFn` resolves to. + * @template TError - The type of errors your `mutationFn` may throw. + * @template TVariables - The type of the variable passed to `mutateAsync`. + * @template TOnMutateResult - The type returned by `onMutate`, passed to `onSuccess`/`onError`/`onSettled` as + * their `onMutateResult` parameter — useful for optimistic-update rollback data. + */ export type UseMutateAsyncFunction< TData = unknown, TError = DefaultError, @@ -175,6 +292,16 @@ export type UseMutateAsyncFunction< TOnMutateResult = unknown, > = MutateFunction +/** + * The result of `useMutation`. Same as {@link MutationObserverResult} from `@tanstack/query-core`, with + * `mutate` narrowed to the fire-and-forget {@link UseMutateFunction} signature, plus the added `mutateAsync`. + * + * @template TData - The type your `mutationFn` resolves to. + * @template TError - The type of errors your `mutationFn` may throw. + * @template TVariables - The type of the variable passed to `mutate`/`mutateAsync`. + * @template TOnMutateResult - The type returned by `onMutate`, passed to `onSuccess`/`onError`/`onSettled` as + * their `onMutateResult` parameter — useful for optimistic-update rollback data. + */ export type UseBaseMutationResult< TData = unknown, TError = DefaultError, @@ -184,6 +311,9 @@ export type UseBaseMutationResult< MutationObserverResult, { mutate: UseMutateFunction } > & { + /** + * Similar to `mutate`, but returns a promise which can be awaited. + */ mutateAsync: UseMutateAsyncFunction< TData, TError, @@ -192,6 +322,15 @@ export type UseBaseMutationResult< > } +/** + * The result of `useMutation`. Same as {@link UseBaseMutationResult}. + * + * @template TData - The type your `mutationFn` resolves to. + * @template TError - The type of errors your `mutationFn` may throw. + * @template TVariables - The type of the variable passed to `mutate`/`mutateAsync`. + * @template TOnMutateResult - The type returned by `onMutate`, passed to `onSuccess`/`onError`/`onSettled` as + * their `onMutateResult` parameter — useful for optimistic-update rollback data. + */ export type UseMutationResult< TData = unknown, TError = DefaultError, diff --git a/packages/solid-query/src/useInfiniteQuery.ts b/packages/solid-query/src/useInfiniteQuery.ts index 9dcff4b185..36655925a7 100644 --- a/packages/solid-query/src/useInfiniteQuery.ts +++ b/packages/solid-query/src/useInfiniteQuery.ts @@ -19,6 +19,54 @@ import type { UndefinedInitialDataInfiniteOptions, } from './infiniteQueryOptions' +/** + * 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. + * + * @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 {@link infiniteQueryOptions} to share these options between `useInfiniteQuery` and imperative APIs like `queryClient.infiniteQuery`. + * @param options - An accessor returning the {@link DefinedInitialDataInfiniteOptions} to use — everything you + * can pass to `useInfiniteQuery`, with `initialData` set. + * @param queryClient - An accessor for a custom `QueryClient`. Otherwise, the one from the nearest context + * will be used. + * @returns 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` shape. + * + * @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 ( + *
    + * {projectsQuery.isError ? Error: {projectsQuery.error.message} : null} + *
      + * + * {(page) => {(p) =>
    • {p.name}
    • }
      } + *
      + *
    + *
    + * ) + * } + * ``` + */ export function useInfiniteQuery< TQueryFnData, TError = DefaultError, @@ -35,6 +83,109 @@ export function useInfiniteQuery< >, queryClient?: Accessor, ): DefinedUseInfiniteQueryResult + +/** + * The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of + * `initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`. + * + * @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 {@link infiniteQueryOptions} to share these options between `useInfiniteQuery` and imperative APIs like `queryClient.infiniteQuery`. + * @param options - An accessor returning the {@link UndefinedInitialDataInfiniteOptions} to use — everything + * you can pass to `useInfiniteQuery`. + * @param queryClient - An accessor for a custom `QueryClient`. Otherwise, the one from the nearest context + * will be used. + * @returns 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` shape. + * + * @example + * 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 ( + * + * Loading... + * Error: {projectsQuery.error.message} + * + *
      + * + * {(page) => {(p) =>
    • {p.name}
    • }
      } + *
      + *
    + * + *
    + *
    + * ) + * } + * ``` + * + * @example + * 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 ( + * + * Loading... + * Error: {projectsQuery.error.message} + * + *
      + * + * {(page) => {(p) =>
    • {p.name}
    • }
      } + *
      + *
    + *
    {projectsQuery.isFetchingNextPage ? 'Loading more...' : null}
    + *
    + *
    + * ) + * } + * ``` + */ export function useInfiniteQuery< TQueryFnData, TError = DefaultError, diff --git a/packages/solid-query/src/useIsFetching.ts b/packages/solid-query/src/useIsFetching.ts index 96a4f23b00..b7772d3774 100644 --- a/packages/solid-query/src/useIsFetching.ts +++ b/packages/solid-query/src/useIsFetching.ts @@ -4,6 +4,28 @@ import type { QueryFilters } from '@tanstack/query-core' import type { QueryClient } from './QueryClient' import type { Accessor } from 'solid-js' +/** + * 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). + * + * @param filters - An accessor returning the {@link QueryFilters} to narrow down the matched queries. + * @param queryClient - An accessor for a custom `QueryClient`. Otherwise, the one from the nearest context + * will be used. + * @returns 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 ? Loading posts... : null + * } + * ``` + */ export function useIsFetching( filters?: Accessor, queryClient?: Accessor, diff --git a/packages/solid-query/src/useIsMutating.ts b/packages/solid-query/src/useIsMutating.ts index 86e6a8bea5..eb1dfbf420 100644 --- a/packages/solid-query/src/useIsMutating.ts +++ b/packages/solid-query/src/useIsMutating.ts @@ -4,6 +4,27 @@ import type { MutationFilters } from '@tanstack/query-core' import type { QueryClient } from './QueryClient' import type { Accessor } from 'solid-js' +/** + * The `useIsMutating` hook returns the `number` of mutations that your application currently has `pending` + * (useful for app-wide loading indicators). + * + * @param filters - An accessor returning the {@link MutationFilters} to narrow down the matched mutations. + * @param queryClient - An accessor for a custom `QueryClient`. Otherwise, the one from the nearest context + * will be used. + * @returns 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 ? Saving posts... : null + * } + * ``` + */ export function useIsMutating( filters?: Accessor, queryClient?: Accessor, diff --git a/packages/solid-query/src/useMutation.ts b/packages/solid-query/src/useMutation.ts index 2d19678baf..e4ffbf4d0a 100644 --- a/packages/solid-query/src/useMutation.ts +++ b/packages/solid-query/src/useMutation.ts @@ -11,7 +11,38 @@ import type { } from './types' import type { Accessor } from 'solid-js' -// HOOK +/** + * @param options - An accessor returning the {@link UseMutationOptions} to use. + * @param queryClient - An accessor for a custom `QueryClient`. Otherwise, the one from the nearest context + * will be used. + * @returns `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. + * + * @example + * ```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 ( + * + * ) + * } + * ``` + */ export function useMutation< TData = unknown, TError = DefaultError, diff --git a/packages/solid-query/src/useMutationState.ts b/packages/solid-query/src/useMutationState.ts index 82f39cc1b4..ad90a85cb9 100644 --- a/packages/solid-query/src/useMutationState.ts +++ b/packages/solid-query/src/useMutationState.ts @@ -48,6 +48,79 @@ function getResult< ) } +/** + * `useMutationState` is a hook that gives you access to all mutations in the `MutationCache`. You can pass + * `filters` ({@link MutationFilters}) to narrow down your mutations, and `select` to transform the mutation + * state. + * + * @param options - An accessor returning the `filters` to narrow down matched mutations, and an optional + * `select` to transform the mutation state. + * @param queryClient - An accessor for a custom `QueryClient`. Otherwise, the one from the nearest context + * will be used. + * @returns An accessor for an array of whatever `select` returns for each matching mutation. + * + * @example + * 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... + * } + * ``` + * + * @example + * 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 ( + * + * ) + * } + * ``` + * + * @example + * 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 {latestPost()?.title} + * } + * ``` + */ export function useMutationState< TResult = MutationState, TMutation extends Mutation = diff --git a/packages/solid-query/src/useQueries.ts b/packages/solid-query/src/useQueries.ts index 9bf909634b..cb6669422e 100644 --- a/packages/solid-query/src/useQueries.ts +++ b/packages/solid-query/src/useQueries.ts @@ -184,6 +184,92 @@ type QueriesResults< > : { [K in keyof T]: GetResults } +/** + * The `useQueries` hook can be used to fetch a variable number of queries. + * + * The `queries` key accepts an array with query option objects identical to `useQuery`. 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. + * @param queriesOptions - An accessor returning the `queries` array to run, and an optional `combine` + * function. + * @param queryClient - An accessor for a custom `QueryClient`. Otherwise, the one from the nearest context + * will be used. + * @returns 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. + * + * @example + * ```tsx + * import { For } from 'solid-js' + * import { useQueries } from '@tanstack/solid-query' + * + * function Posts(props: { ids: Array }) { + * const postQueries = useQueries(() => ({ + * queries: props.ids.map((id) => ({ + * queryKey: ['post', id], + * queryFn: () => fetchPost(id), + * staleTime: Infinity, + * })), + * })) + * + * return ( + *
      + * + * {(postQuery) => { + * if (postQuery.isPending) return
    • Loading...
    • + * if (postQuery.isError) return
    • Error: {postQuery.error.message}
    • + * return
    • {postQuery.data.title}
    • + * }} + *
      + *
    + * ) + * } + * ``` + * + * @example + * 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 }) { + * 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 ( + * + * {(post) =>
  • {post?.title}
  • }
    + * + * } + * > + * Loading... + * Error loading posts + *
    + * ) + * } + * ``` + */ export function useQueries< T extends Array, TCombinedResult extends QueriesResults = QueriesResults, diff --git a/packages/solid-query/src/useQuery.ts b/packages/solid-query/src/useQuery.ts index e8efb4796a..e9e238d1c6 100644 --- a/packages/solid-query/src/useQuery.ts +++ b/packages/solid-query/src/useQuery.ts @@ -14,6 +14,167 @@ import type { UndefinedInitialDataOptions, } from './queryOptions' +/** + * @see {@link queryOptions} to share these options between `useQuery` and imperative APIs like `queryClient.query`. + * @param options - An accessor returning the {@link UndefinedInitialDataOptions} to use — everything you can + * pass to `useQuery`. + * @param queryClient - An accessor for a custom `QueryClient`. Otherwise, the one from the nearest context + * will be used. + * @returns 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. + * + * @example + * ```tsx + * import { For, Match, Switch } from 'solid-js' + * import { useQuery } from '@tanstack/solid-query' + * + * function Posts() { + * const postsQuery = useQuery(() => ({ + * queryKey: ['posts'], + * queryFn: fetchPosts, + * })) + * + * return ( + * + * Loading... + * Error: {postsQuery.error.message} + * + *
      + * {(post) =>
    • {post.title}
    • }
      + *
    + *
    {postsQuery.isFetching ? 'Background Updating...' : ' '}
    + *
    + *
    + * ) + * } + * ``` + * + * @example + * `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 ( + * + * Loading... + * Error: {postsQuery.error.message} + * {postsQuery.data} posts + * + * ) + * } + * ``` + * + * @example + * 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 ( + * {postQuery.data?.title}}> + * Select a post + * Loading... + * Error: {postQuery.error.message} + * + * ) + * } + * ``` + * + * @example + * 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 ( + * {postQuery.data?.title}}> + * Select a post + * Loading... + * Error: {postQuery.error.message} + * + * ) + * } + * ``` + * + * @example + * 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>(['posts']) + * ?.find((post) => post.id === props.postId), + * })) + * + * return postQuery.isError ? Error: {postQuery.error.message} :

    {postQuery.data?.title}

    + * } + * ``` + * + * @example + * 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 ( + *
    + *
      + * {(post) =>
    • {post.title}
    • }
      + *
    + * + *
    + * ) + * } + * ``` + */ export function useQuery< TQueryFnData = unknown, TError = DefaultError, @@ -24,6 +185,44 @@ export function useQuery< queryClient?: () => QueryClient, ): UseQueryResult +/** + * This overload is selected when `initialData` is set, so the resulting `data` is never `undefined`. + * + * @see {@link queryOptions} to share these options between `useQuery` and imperative APIs like `queryClient.query`. + * @param options - An accessor returning the {@link DefinedInitialDataOptions} to use — everything you can + * pass to `useQuery`, with `initialData` set. + * @param queryClient - An accessor for a custom `QueryClient`. Otherwise, the one from the nearest context + * will be used. + * @returns 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. + * + * @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 ( + *
    + * {postsQuery.isError ? Error: {postsQuery.error.message} : null} + *
      + * {(post) =>
    • {post.title}
    • }
      + *
    + *
    + * ) + * } + * ``` + */ export function useQuery< TQueryFnData = unknown, TError = DefaultError,