useApiMutation — React hook for mutations
A React hook over an ApiClient endpoint for writes (POST/PUT/DELETE/PATCH). Unlike
useApiQuery, the request does not start automatically — you trigger it with
mutate/mutateAsync. Mutations aren't cached (by REST method), and their invalidatesTags invalidate
the cache — active useApiQuery hooks of neighbouring endpoints refetch on their own via the
invalidation bus.
Import
import { useApiMutation } from 'synapse-storage/react'Usage
const endpoints = pokemonApiClient.getEndpoints()
function CreatePokemon() {
const { mutate, isLoading, isError, error } = useApiMutation(endpoints.createPokemon)
return (
<form
onSubmit={(e) => {
e.preventDefault()
mutate({ name: 'Pikachu' }) // fire-and-forget
}}
>
<button disabled={isLoading}>Create</button>
{isError && <Error message={error?.message} />}
</form>
)
}Return value
useApiMutation(endpoint, options?) returns:
| Field | Type | Description |
|---|---|---|
| mutate | (params) => void | Run the mutation; errors are not thrown (read error/isError) |
| mutateAsync | (params) => Promise<QueryResult> | Run and await; rejects on error |
| data | TData | undefined | Data of a successful response |
| error | Error | undefined | Mutation error |
| status | 'idle' | 'loading' | 'success' | 'error' | Current status |
| isLoading | boolean | status === 'loading' |
| isError | boolean | status === 'error' |
| isSuccess | boolean | status === 'success' |
| reset | () => void | Reset state back to idle |
options is QueryOptions (signal, headers, timeout, retry, …).
mutate vs mutateAsync
mutate(params)— fire-and-forget. The rejection is swallowed (state already reflects the error), so you don't need a.catch. Best for simple form submits.mutateAsync(params)— returns the promise and rethrows on error, so you canawaitand branch in flow:
Invalidating related queries
Give the mutation endpoint invalidatesTags; any useApiQuery whose endpoint tags intersect will
refetch automatically. No manual cache wiring required.
// endpoint config
createPokemon: create({
request: (body) => ({ path: '/pokemon', method: 'POST', body }),
invalidatesTags: ['PokemonList'],
})
// getList endpoint has tags: ['PokemonList']
// → after a successful createPokemon, an active useApiQuery(getList) refetchesNotes
StrictMode-safe. On unmount the in-flight request is aborted and state updates are skipped.
Mutations are never written to the cache (only GET is cached), so there's no
fromCachehere.
See also
useApiQuery — the companion hook for reads.
ApiClient — caching, tags and the invalidation bus.