You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GraphQL/Apollo/React中完成多轮Mutation后重新获取数据

问题场景与现有尝试

业务需求

  • 需调用两个useMutation操作数据库:完成创建/更新操作
  • 第二个Mutation必须在第一个执行成功后触发,且需要遍历数组循环调用第二个Mutation
  • 所有Mutation执行完成后,必须重新调用另一个API以更新缓存(因为这两个Mutation会影响缓存数据)

现有尝试及问题

方法1:使用Promise.all

const [creatEnrollment] = useMutation(mut1)
const [updateEnrollment] = useMutation(mut2)
const [toFetch, {loading, error, data}] = useLazyQuery(UsersDocument)

await Promise.all([creatEnrollment(), updateEnrollment()])
const result = () => toFetch({
   variables: {name: 'i'}
})
  • 问题:无法保证第二个Mutation在第一个之后执行,也无法实现循环调用第二个Mutation

方法2:使用React Query的onSuccess回调

const mutate1 = useMutation((data) => axios.post('/something', { data }))
const mutate2 = useMutation(somethingResult => axios.put('/somethingElse', { somethingResult }))

<button onClick={() => {
    mutate1.mutate('data', {
      onSuccess: mutate2.mutate
    })
}} />
  • 问题:不知道如何循环调用mutate2,也不清楚如何在所有mutate2执行完成后触发数据重获取

解决方案

可以结合onSuccess回调和Promise.all实现需求,具体步骤如下:

1. 定义Mutation与缓存更新查询

import { useMutation, useLazyQuery } from '@tanstack/react-query';
import axios from 'axios';

// 第一个创建操作的Mutation
const { mutate: createEnrollment } = useMutation(
  (createData) => axios.post('/api/enrollments', createData),
);

// 第二个更新操作的Mutation(返回Promise方便后续批量处理)
const { mutate: updateEnrollment } = useMutation(
  (updateData) => axios.put('/api/enrollments/update', updateData),
);

// 用于更新缓存的Lazy Query
const [fetchUsers, { isLoading: isRefetching }] = useLazyQuery(UsersDocument);

2. 实现依赖与循环调用逻辑

先等待第一个Mutation执行成功,再遍历数组批量执行第二个Mutation,最后触发缓存重获取:

const handleBatchOperations = async (createData, updateItems) => {
  // 等待第一个创建Mutation执行完成
  await new Promise((resolve, reject) => {
    createEnrollment(createData, {
      onSuccess: resolve,
      onError: reject,
    });
  });

  // 遍历数组,把每个更新操作包装成Promise
  const updatePromises = updateItems.map(item => 
    new Promise((resolve, reject) => {
      updateEnrollment(item, {
        onSuccess: resolve,
        onError: reject,
      });
    })
  );

  // 等待所有更新Mutation执行完成
  await Promise.all(updatePromises);

  // 所有操作完成后,触发缓存重获取
  await fetchUsers({ variables: { name: 'i' } });
};

3. 组件中触发执行

在按钮点击或其他交互时调用处理函数:

<button 
  onClick={() => handleBatchOperations(yourCreateData, yourUpdateArray)}
  disabled={isRefetching}
>
  执行批量操作
</button>

关键说明

  • 用Promise包装mutate调用,通过await确保第一个Mutation执行完成后再处理后续逻辑
  • 遍历待更新数组,将每个updateEnrollment调用转为Promise,用Promise.all等待全部更新完成
  • 所有操作结束后调用缓存查询,保证前端数据与后端同步

内容的提问来源于stack exchange,提问作者Hongli Bu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 08:20:33