译零 TransZero · TanStack Query 中文文档
主站

injectMutation

更新于 2026-11-02 Angular 查看英文原文 ↗
TypeScript
1function injectMutation<TData = unknown, TError = Error, TVariables = void, TOnMutateResult = unknown>(injectMutationFn: () => CreateMutationOptions<TData, TError, TVariables, TOnMutateResult>, options?: InjectMutationOptions): CreateMutationResult<TData, TError, TVariables, TOnMutateResult>;

定义于:packages/angular-query-experimental/src/inject-mutation.ts:172

与查询不同,修改通常用于创建/更新/删除数据或执行服务端副作用。 injectMutation 是用于此目的的函数。与查询不同,修改不会自动运行。

类型参数

TData

TData = unknown

TError

TError = Error

TVariables

TVariables = void

TOnMutateResult

TOnMutateResult = unknown

参数

injectMutationFn

() => CreateMutationOptions<TData, TError, TVariables, TOnMutateResult>

一个返回修改选项的函数。类似于 Angular 中的 computed,该函数在响应式上下文中运行,因此其中读取的信号会驱动修改的选项。

injectMutationFn 属性

属性 类型 默认值 描述
gcTime? number undefined 未使用/非活跃修改在内存中保留的时间(毫秒),超时后将被垃圾回收。默认为 5 * 60 * 1000(5 分钟),SSR 期间为 Infinity。
meta? Record<string, unknown> undefined 存储在修改缓存条目上的额外负载。可用于传递可在 mutation 可用的任意位置读取的信息,例如 MutationCache 的 onError 和 onSuccess 回调。
mutationFn? (variables: TVariables, context: MutationFunctionContext) => Promise<TData> undefined 执行该修改所运行的异步任务的函数。必需,除非已通过 queryClient.setMutationDefaults 为匹配的 mutationKey 设置了默认修改函数。接收传入 mutate 的 variables,以及一个包含 QueryClient、mutationKey 和 meta 的 MutationFunctionContext。必须返回一个解析修改数据的 Promise。
mutationKey? readonly unknown[] undefined 此修改所用的键。可选,但若要继承通过 queryClient.setMutationDefaults 注册的默认值,或要将此修改与 useMutationState 或 queryClient.isMutating 匹配,则必须提供。
networkMode? "online" | "always" | "offlineFirst" 'online' 控制是否允许修改基于当前网络连接状态运行。参见 Network Mode 获取更多信息。
onError? (error: TError, variables: TVariables, onMutateResult: TOnMutateResult | undefined, context: MutationFunctionContext) => unknown undefined 当修改遇到错误时调用此函数,并传入错误。若返回 Promise,则会在 onSettled 运行前等待其完成。
onMutate? (variables: TVariables, context: MutationFunctionContext) => TOnMutateResult | Promise<TOnMutateResult> undefined 在修改函数运行前调用此函数,并接收相同的变量。适用于应用乐观更新(期望修改成功)。其返回值将作为 onMutateResult 传给 onSuccess、onError 和 onSettled,乐观更新通常在此处回滚。若返回 Promise,则会在修改函数运行前等待其完成。
onSettled? (data: TData | undefined, error: TError | null, variables: TVariables, onMutateResult: TOnMutateResult | undefined, context: MutationFunctionContext) => unknown undefined 当修改成功或出错时调用此函数,并传入数据或错误。若返回 Promise,则会在修改最终确定前等待其完成。
onSuccess? (data: TData, variables: TVariables, onMutateResult: TOnMutateResult, context: MutationFunctionContext) => unknown undefined 当修改成功时调用此函数,并传入修改结果。若返回 Promise,则会在 onSettled 运行前等待其完成。
retry? | number | false | true | ((failureCount: number, error: TError) => boolean) 0 若为 false,失败的修改默认不重试;若为 true,失败的修改将无限重试;若设为整数(如 3),则失败的修改将重试直至失败次数达到该数值;若设为函数 (failureCount, error) => boolean,则失败的修改将重试直至该函数返回 false。
retryDelay? number | ((failureCount: number, error: TError) => number) undefined 此函数接收一个 retryAttempt 整数和实际 Error,并返回下次尝试前应延迟的毫秒数。默认为一个应用指数退避(上限为 30 秒)的函数。
scope? MutationScope undefined 控制此修改是与其他修改并行运行还是等待轮到自己。共享相同 scope.id 的修改将按启动顺序串行运行。若未指定作用域,则修改将在触发后立即运行。
throwOnError? boolean | ((error: TError) => boolean) false 是否应抛出错误而非设置 error 属性。若设为 true,所有错误都将抛出至最近的错误边界。若设为函数,则会传入错误并应返回布尔值,指示是否抛出错误(true)或将其作为状态返回(false)。

options?

InjectMutationOptions

其他配置

options 属性

属性 类型 描述
injector? Injector 创建修改所在的 Injector。若未提供,将改用当前注入上下文(通过 inject)。

返回值

CreateMutationResult<TData, TError, TVariables, TOnMutateResult>

修改结果。值字段以 Signal 形式暴露 —— 通过调用它们来读取 data/error(例如 mutation.data())—— 而函数字段(mutate、mutateAsync、reset)则直接调用,保持不变。isSuccess/isError/isPending/isIdle 是类型守卫方法,可用于缩小 data 是否已定义的判断范围。

备注

mutate/mutateAsync 还接受每调用一次的 onSuccess/onError/onSettled 回调作为第二个参数,这有助于在不将调用点副作用(例如导航)耦合到共享修改定义的情况下触发它们。在 injectMutationFn 中定义的回调对每次修改均生效;而每次调用的回调仅对最近一次调用生效 — mutateAsync 为每次调用提供一个 Promise,因此你可以等待 Promise.all/Promise.allSettled 的多次调用并分别查看每次的结果。

参见

mutationOptions 用于在多个 injectMutation 调用点之间共享这些选项,或通过其 mutationKey 在其他位置查找该修改(例如使用 injectMutationState)。

示例

angular-ts
1@Component({2  selector: 'todos',3  template: `4    @if (addMutation.isPending()) {5      <span>Adding todo...</span>6    } @else if (addMutation.isError()) {7      <div>An error occurred: {{ addMutation.error()?.message }}</div>8    }9    <button (click)="addMutation.mutate('Item')">Add</button>10  `,11})12export class Todos {13  readonly #queryClient = inject(QueryClient)14 15  readonly addMutation = injectMutation(() => ({16    mutationFn: addTodo,17    onSuccess: () => this.#queryClient.invalidateQueries({ queryKey: ['todos'] }),18  }))19}

通过 onMutate 实现乐观更新,并在 onError 中回滚:

angular-ts
1@Component({2  selector: 'todos',3  template: `<button (click)="addMutation.mutate('Item')">Add</button>`,4})5export class Todos {6  readonly #queryClient = inject(QueryClient)7 8  readonly addMutation = injectMutation(() => ({9    mutationFn: addTodo,10    onMutate: async (newTodo) => {11      await this.#queryClient.cancelQueries({ queryKey: ['todos'] })12      const previousTodos = this.#queryClient.getQueryData<Array<string>>(['todos'])13 14      this.#queryClient.setQueryData<Array<string>>(['todos'], (old) => [15        ...(old ?? []),16        newTodo,17      ])18 19      // Passed to `onError` as `onMutateResult` if the mutation fails.20      return { previousTodos }21    },22    onError: (_err, _newTodo, onMutateResult) => {23      this.#queryClient.setQueryData(['todos'], onMutateResult?.previousTodos)24    },25    onSettled: () => {26      this.#queryClient.invalidateQueries({ queryKey: ['todos'] })27    },28  }))29}

传给 mutate 的每次调用的回调仅对最后一次调用生效 — mutateAsync 为每次调用提供一个 Promise,因此你可以在它们全部成功时等待全部结果:

angular-ts
1@Component({2  selector: 'todos',3  template: `4    <button (click)="handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])">Add all</button>5  `,6})7export class Todos {8  readonly #queryClient = inject(QueryClient)9 10  readonly addMutation = injectMutation(() => ({11    mutationFn: addTodo,12    onSuccess: () => this.#queryClient.invalidateQueries({ queryKey: ['todos'] }),13  }))14 15  async handleAddAll(todos: Array<string>) {16    try {17      await Promise.all(todos.map((todo) => this.addMutation.mutateAsync(todo)))18    } catch (error) {19      console.error('Failed to add todos:', error)20    }21  }22}

如果上述某些修改可独立于其他修改而失败,且你想知道哪些失败了(而非在第一个拒绝时就丢失该信息),请将 Promise.all 替换为 Promise.allSettled:

angular-ts
1@Component({2  selector: 'todos',3  template: `4    <button (click)="handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])">Add all</button>5  `,6})7export class Todos {8  readonly #queryClient = inject(QueryClient)9 10  readonly addMutation = injectMutation(() => ({11    mutationFn: addTodo,12    onSuccess: () => this.#queryClient.invalidateQueries({ queryKey: ['todos'] }),13  }))14 15  async handleAddAll(todos: Array<string>) {16    const addResults = await Promise.allSettled(17      todos.map((todo) => this.addMutation.mutateAsync(todo)),18    )19 20    addResults.forEach((addResult, index) => {21      if (addResult.status === 'rejected') {22        console.error(`Failed to add "${todos[index]}":`, addResult.reason)23      }24    })25  }26}

本页为 TanStack Query 文档(Angular 版)的非官方中文翻译,原文由上游团队维护,遵循 MIT 许可。 译文如有偏差,以英文原文为准。

译自上游 59d11de