- Solid Reference
- Functions / QueryClientProvider
- Functions / defaultShouldDehydrateMutation
- Functions / defaultShouldDehydrateQuery
- Functions / dehydrate
- Functions / dehydrateQuery
- Functions / experimental_streamedQuery
- Functions / hashKey
- Functions / hydrate
- Functions / infiniteQueryOptions
- Functions / isCancelledError
- Functions / keepPreviousData
- Functions / matchMutation
- Functions / matchQuery
- Functions / mutationOptions
- Functions / noop
- Functions / partialMatchKey
- Functions / queryOptions
- Functions / replaceEqualDeep
- Functions / shouldThrowError
- Functions / useInfiniteQuery
- Functions / useIsFetching
- Functions / useIsMutating
- Functions / useIsRestoring
- Functions / useMutation
- Functions / useMutationState
- Functions / useQueries
- Functions / useQuery
- Functions / useQueryClient
- Classes / CancelledError
- Classes / InfiniteQueryObserver
- Classes / Mutation
- Classes / MutationCache
- Classes / MutationObserver
- Classes / QueriesObserver
- Classes / Query
- Classes / QueryCache
- Classes / QueryClient
- Classes / QueryObserver
- Interfaces / CancelOptions
- Interfaces / DefaultOptions
- Interfaces / DehydrateOptions
- Interfaces / DehydratedState
- Interfaces / EnsureQueryDataOptions
- Interfaces / FetchNextPageOptions
- Interfaces / FetchPreviousPageOptions
- Interfaces / FetchQueryOptions
- Interfaces / FocusManager
- Interfaces / HydrateOptions
- Interfaces / InfiniteData
- Interfaces / InfiniteQueryObserverBaseResult
- Interfaces / InfiniteQueryObserverLoadingErrorResult
- Interfaces / InfiniteQueryObserverLoadingResult
- Interfaces / InfiniteQueryObserverOptions
- Interfaces / InfiniteQueryObserverPendingResult
- Interfaces / InfiniteQueryObserverPlaceholderResult
- Interfaces / InfiniteQueryObserverRefetchErrorResult
- Interfaces / InfiniteQueryObserverSuccessResult
- Interfaces / InfiniteQueryOptions
- Interfaces / InfiniteQueryPageParamsOptions
- Interfaces / InitialPageParam
- Interfaces / InvalidateOptions
- Interfaces / InvalidateQueryFilters
- Interfaces / MutateOptions
- Interfaces / MutationCacheConfig
- Interfaces / MutationFilters
- Interfaces / MutationObserverBaseResult
- Interfaces / MutationObserverErrorResult
- Interfaces / MutationObserverIdleResult
- Interfaces / MutationObserverLoadingResult
- Interfaces / MutationObserverOptions
- Interfaces / MutationObserverSuccessResult
- Interfaces / MutationOptions
- Interfaces / MutationState
- Interfaces / NotifyEvent
- Interfaces / OnlineManager
- Interfaces / QueriesObserverOptions
- Interfaces / QueryCacheConfig
- Interfaces / QueryClientConfig
- Interfaces / QueryExecuteOptions
- Interfaces / QueryFilters
- Interfaces / QueryObserverBaseResult
- Interfaces / QueryObserverLoadingErrorResult
- Interfaces / QueryObserverLoadingResult
- Interfaces / QueryObserverOptions
- Interfaces / QueryObserverPendingResult
- Interfaces / QueryObserverPlaceholderResult
- Interfaces / QueryObserverRefetchErrorResult
- Interfaces / QueryObserverSuccessResult
- Interfaces / QueryOptions
- Interfaces / QueryState
- Interfaces / RefetchOptions
- Interfaces / RefetchQueryFilters
- Interfaces / Register
- Interfaces / ResetOptions
- Interfaces / ResultOptions
- Interfaces / SetDataOptions
- Interfaces / TimeoutManager
- Interfaces / UseBaseQueryOptions
- Types / AnyDataTag
- Types / DataTag
- Types / DefaultError
- Types / DefaultedInfiniteQueryObserverOptions
- Types / DefaultedQueryObserverOptions
- Types / DefinedInfiniteQueryObserverResult
- Types / DefinedInitialDataInfiniteOptions
- Types / DefinedInitialDataOptions
- Types / DefinedQueryObserverResult
- Types / DefinedUseBaseQueryResult
- Types / DefinedUseInfiniteQueryResult
- Types / DefinedUseQueryResult
- Types / DistributiveOmit
- Types / EnsureInfiniteQueryDataOptions
- Types / FetchInfiniteQueryOptions
- Types / FetchStatus
- Types / GetNextPageParamFunction
- Types / GetPreviousPageParamFunction
- Types / InferDataFromTag
- Types / InferErrorFromTag
- Types / InfiniteQueryExecuteOptions
- Types / InfiniteQueryObserverResult
- Types / InitialDataFunction
- Types / ManagedTimerId
- Types / MutateFunction
- Types / MutateFunctionRest
- Types / MutationCacheNotifyEvent
- Types / MutationFunction
- Types / MutationFunctionContext
- Types / MutationKey
- Types / MutationMeta
- Types / MutationObserverResult
- Types / MutationScope
- Types / MutationStatus
- Types / NetworkMode
- Types / NonUndefinedGuard
- Types / NotifyEventType
- Types / NotifyOnChangeProps
- Types / OmitKeyof
- Types / Override
- Types / PlaceholderDataFunction
- Types / QueriesPlaceholderDataFunction
- Types / QueryBooleanOption
- Types / QueryCacheNotifyEvent
- Types / QueryClientProviderProps
- Types / QueryFunction
- Types / QueryFunctionContext
- Types / QueryKey
- Types / QueryKeyHashFunction
- Types / QueryKeyWithDataTag
- Types / QueryMeta
- Types / QueryObserverResult
- Types / QueryPersister
- Types / QueryStatus
- Types / SkipToken
- Types / StaleTime
- Types / StaleTimeFunction
- Types / ThrowOnError
- Types / TimeoutCallback
- Types / TimeoutProvider
- Types / UndefinedInitialDataInfiniteOptions
- Types / UndefinedInitialDataOptions
- Types / UnsetMarker
- Types / Updater
- Types / UseBaseMutationResult
- Types / UseBaseQueryResult
- Types / UseInfiniteQueryOptions
- Types / UseInfiniteQueryResult
- Types / UseMutateAsyncFunction
- Types / UseMutateFunction
- Types / UseMutationOptions
- Types / UseMutationResult
- Types / UseQueryOptions
- Types / UseQueryResult
- Types / WithRequired
- Types / dataTagErrorSymbol
- Types / dataTagSymbol
- Variables / IsRestoringProvider
- Variables / QueryClientContext
- Variables / createInfiniteQuery
- Variables / createMutation
- Variables / createQueries
- Variables / createQuery
- Variables / dataTagErrorSymbol
- Variables / dataTagSymbol
- Variables / defaultScheduler
- Variables / environmentManager
- Variables / focusManager
- Variables / isServer
- Variables / notifyManager
- Variables / onlineManager
- Variables / skipToken
- Variables / timeoutManager
- Variables / unsetMarker
useMutation
function useMutation<TData = unknown, TError = Error, TVariables = void, TOnMutateResult = unknown>(options: UseMutationOptions<TData, TError, TVariables, TOnMutateResult>, queryClient?: Accessor<QueryClient>): UseMutationResult<TData, TError, TVariables, TOnMutateResult>;Defined in: packages/solid-query/src/useMutation.ts:170
Unlike queries, mutations are typically used to create/update/delete data or perform server side-effects. useMutation is the primitive for that.
Type Parameters#
TData#
TData = unknown
TError#
TError = Error
TVariables#
TVariables = void
TOnMutateResult#
TOnMutateResult = unknown
Parameters#
options#
UseMutationOptions<TData, TError, TVariables, TOnMutateResult>
An accessor returning the UseMutationOptions to use.
options properties#
Built from MutationOptions. See the type above for what it changes.
queryClient?#
Accessor<QueryClient>
An accessor for a custom QueryClient. Otherwise, the one from the nearest context will be used.
Returns#
UseMutationResult<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.
Result properties#
Built from MutationObserverBaseResult. See the type above for what it changes.
Examples#
import { useMutation, useQueryClient } from '@tanstack/solid-query'
function TodoItem(props: { id: number }) {
const queryClient = useQueryClient()
const deleteTodoMutation = useMutation(() => ({
mutationFn: deleteTodo,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
}))
return (
<button onClick={() => deleteTodoMutation.mutate({ id: props.id })} disabled={deleteTodoMutation.isPending}>
Delete
</button>
)
}Rendering the mutation's own state, rather than just firing it off:
import { Match, Switch } from 'solid-js'
import { useMutation, useQueryClient } from '@tanstack/solid-query'
function AddTodo() {
const queryClient = useQueryClient()
const addMutation = useMutation(() => ({
mutationFn: addTodo,
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
}))
return (
<Switch fallback={<button onClick={() => addMutation.mutate('Item')}>Add</button>}>
<Match when={addMutation.isPending}>Adding todo...</Match>
<Match when={addMutation.isError}>
<div>An error occurred: {addMutation.error?.message}</div>
<button onClick={() => addMutation.mutate('Item')}>Add</button>
</Match>
</Switch>
)
}Optimistic update via onMutate, rolling back on onError:
import { useMutation, useQueryClient } from '@tanstack/solid-query'
function AddTodo() {
const queryClient = useQueryClient()
const addMutation = useMutation(() => ({
mutationFn: addTodo,
onMutate: async (newTodo) => {
await queryClient.cancelQueries({ queryKey: ['todos'] })
const previousTodos = queryClient.getQueryData<Array<string>>(['todos'])
queryClient.setQueryData<Array<string>>(['todos'], (old) => [
...(old ?? []),
newTodo,
])
// Passed to `onError` as `onMutateResult` if the mutation fails.
return { previousTodos }
},
onError: (_err, _newTodo, onMutateResult) => {
queryClient.setQueryData(['todos'], onMutateResult?.previousTodos)
},
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
}))
return (
<button onClick={() => addMutation.mutate('Item')}>Add</button>
)
}Callbacks passed per call to mutate only fire for the last call — mutateAsync gives you a promise per call instead, so you can wait for all of them when they succeed:
import { useMutation, useQueryClient } from '@tanstack/solid-query'
function AddTodos() {
const queryClient = useQueryClient()
const addMutation = useMutation(() => ({
mutationFn: addTodo,
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
}))
async function handleAddAll(todos: Array<string>) {
try {
await Promise.all(todos.map((todo) => addMutation.mutateAsync(todo)))
} catch (error) {
console.error('Failed to add todos:', error)
}
}
return (
<button onClick={() => handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])}>
Add all
</button>
)
}If some of the mutations above can fail independently of the others, and you want to know which ones did — rather than losing that information the moment the first one rejects — swap Promise.all for Promise.allSettled:
import { useMutation, useQueryClient } from '@tanstack/solid-query'
function AddTodos() {
const queryClient = useQueryClient()
const addMutation = useMutation(() => ({
mutationFn: addTodo,
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
}))
async function handleAddAll(todos: Array<string>) {
const addResults = await Promise.allSettled(
todos.map((todo) => addMutation.mutateAsync(todo)),
)
addResults.forEach((addResult, index) => {
if (addResult.status === 'rejected') {
console.error(`Failed to add "${todos[index]}":`, addResult.reason)
}
})
}
return (
<button onClick={() => handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])}>
Add all
</button>
)
}