createMutation
1function createMutation<TData = unknown, TError = Error, TVariables = void, TContext = unknown>(options: Accessor<CreateMutationOptions<TData, TError, TVariables, TContext>>, queryClient?: Accessor<QueryClient>): CreateMutationResult<TData, TError, TVariables, TContext>;定义于:packages/svelte-query/src/createMutation.svelte.ts:165
与查询不同,修改通常用于创建/更新/删除数据或执行服务端副作用。
createMutation 是用于该目的的函数。
类型参数
TData
TData = unknown
TError
TError = Error
TVariables
TVariables = void
TContext
TContext = unknown
参数
options
Accessor<CreateMutationOptions<TData, TError, TVariables, TContext>>
要使用的 CreateMutationOptions,包裹在 Accessor 中,以便选项可响应式更新。
options 属性
基于 MutationObserverOptions 构建。参见上方类型定义以了解其具体变更内容。
queryClient?
使用此参数可指定自定义 QueryClient;否则将使用最近上下文中的 QueryClient。
返回值
CreateMutationResult<TData, TError, TVariables, TContext>
mutate/mutateAsync 还接受每调用一次时传入的 onSuccess/onError/onSettled 回调函数作为第二个参数,这有助于在不将调用点副作用(例如导航)耦合到共享修改定义的情况下触发它们。若你发起多次请求,onSuccess 仅会在你发出的最新一次调用完成后触发。
返回结果属性
基于 MutationObserverBaseResult 构建。参见上方类型定义以了解其具体变更内容。
参阅
mutationOptions 可用于在多个 createMutation 调用点之间共享这些选项,或通过其 mutationKey(例如配合 useMutationState)在其他位置查找该修改。
示例
1<script lang="ts">2 import { createMutation, useQueryClient } from '@tanstack/svelte-query'3 4 const queryClient = useQueryClient()5 6 const addMutation = createMutation(() => ({7 mutationFn: addTodo,8 onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),9 }))10</script>11 12<button13 onclick={() =>14 addMutation.mutate('Item', {15 onError: (error) => console.error('Failed to add item:', error),16 })17 }18>19 Add20</button>渲染修改自身的状态,而不仅仅是触发它:
1<script lang="ts">2 import { createMutation, useQueryClient } from '@tanstack/svelte-query'3 4 const queryClient = useQueryClient()5 6 const addMutation = createMutation(() => ({7 mutationFn: addTodo,8 onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),9 }))10</script>11 12{#if addMutation.isPending}13 Adding todo...14{:else}15 {#if addMutation.isError}16 <div>An error occurred: {addMutation.error.message}</div>17 {/if}18 <button onclick={() => addMutation.mutate('Item')}>Add</button>19{/if}通过 onMutate 实现乐观更新,并在 onError 时回滚:
1<script lang="ts">2 import { createMutation, useQueryClient } from '@tanstack/svelte-query'3 4 const queryClient = useQueryClient()5 6 const addMutation = createMutation(() => ({7 mutationFn: addTodo,8 onMutate: async (newTodo: string) => {9 await queryClient.cancelQueries({ queryKey: ['todos'] })10 const previousTodos = queryClient.getQueryData<Array<string>>(['todos'])11 12 queryClient.setQueryData<Array<string>>(['todos'], (old) => [13 ...(old ?? []),14 newTodo,15 ])16 17 // Passed to `onError` as `onMutateResult` if the mutation fails.18 return { previousTodos }19 },20 onError: (_err, _newTodo, onMutateResult) => {21 queryClient.setQueryData(['todos'], onMutateResult?.previousTodos)22 },23 onSettled: () => {24 queryClient.invalidateQueries({ queryKey: ['todos'] })25 },26 }))27</script>28 29<button onclick={() => addMutation.mutate('Item')}>Add</button>传递给 mutate 的每次调用的回调函数仅对最后一次调用生效 —— mutateAsync 则为每次调用返回一个 Promise,因此你可在所有调用成功后等待全部完成:
1<script lang="ts">2 import { createMutation, useQueryClient } from '@tanstack/svelte-query'3 4 const queryClient = useQueryClient()5 6 const addMutation = createMutation(() => ({7 mutationFn: addTodo,8 onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),9 }))10 11 async function handleAddAll(todos: Array<string>) {12 try {13 await Promise.all(todos.map((todo) => addMutation.mutateAsync(todo)))14 } catch (error) {15 console.error('Failed to add todos:', error)16 }17 }18</script>19 20<button onclick={() => handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])}>21 Add all22</button>若上述某些修改可能独立于其他修改而失败,且你想知道具体哪些失败了(而非在第一个修改拒绝时就丢失该信息),请将 Promise.all 替换为 Promise.allSettled:
1<script lang="ts">2 import { createMutation, useQueryClient } from '@tanstack/svelte-query'3 4 const queryClient = useQueryClient()5 6 const addMutation = createMutation(() => ({7 mutationFn: addTodo,8 onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),9 }))10 11 async function handleAddAll(todos: Array<string>) {12 const addResults = await Promise.allSettled(13 todos.map((todo) => addMutation.mutateAsync(todo)),14 )15 16 addResults.forEach((addResult, index) => {17 if (addResult.status === 'rejected') {18 console.error(`Failed to add "${todos[index]}":`, addResult.reason)19 }20 })21 }22</script>23 24<button onclick={() => handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])}>25 Add all26</button>