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

调用useMutation内部请求成功却无法获取返回数据的问题

tRPC useMutation 无法立即获取返回数据的解决方案

问题核心原因

你遇到的问题本质是**mutate是异步操作**:调用mutate后不会同步返回请求结果,你紧接着访问dataMutation.data时,请求还在处理中,因此值为undefined;而onSuccess是请求成功后触发的回调,自然能拿到正确数据。


解决方案一:在onSuccess回调中处理结果

把依赖返回数据的逻辑(比如更新cardSets、page)移到onSuccess里,同时注意React状态更新的闭包问题,用函数式更新获取最新状态:

// fetch data
const dataMutation = api.post.queryByFilter.useMutation({
  onSuccess(data) {
    console.log("onSuccess: ", data);
    // 在这里处理返回的数据
    const currentDate = new Date();
    currentDate.setMonth(currentDate.getMonth() - monthsBack);
    const getMonth = (currentDate.getMonth() + 1).toString();
    const getYear = currentDate.getFullYear().toString();
    
    // 函数式更新避免闭包问题,获取最新状态
    setCardSets(prev => [
      ...prev,
      { data, month: getMonth, year: getYear }
    ]);
    setPage(prev => prev + 1);
  },
});

const fetchData = () => {
  // 用函数式更新monthsBack,确保状态更新逻辑正确
  setMonthsBack(prev => prev + 1);
  const currentDate = new Date();
  // 因setMonthsBack是异步的,直接用monthsBack+1计算目标日期
  currentDate.setMonth(currentDate.getMonth() - (monthsBack + 1));
  const getMonth = (currentDate.getMonth() + 1).toString();
  const getYear = currentDate.getFullYear().toString();

  dataMutation.mutate({
    company: "google",
    month: getMonth, // 已经是字符串,无需重复toString()
    year: getYear,
  });
};

解决方案二:使用mutateAsync配合async/await

tRPC的useMutation提供了mutateAsync方法,它返回Promise,可通过await等待请求完成,同步获取返回数据:

// fetch data
const dataMutation = api.post.queryByFilter.useMutation();

const fetchData = async () => {
  setMonthsBack(prev => prev + 1);
  const currentDate = new Date();
  currentDate.setMonth(currentDate.getMonth() - (monthsBack + 1));
  const getMonth = (currentDate.getMonth() + 1).toString();
  const getYear = currentDate.getFullYear().toString();

  try {
    // await等待请求完成,直接拿到返回数据
    const data = await dataMutation.mutateAsync({
      company: "google",
      month: getMonth,
      year: getYear,
    });
    console.log("Fetch Data: ", data);
    
    // 处理数据
    setCardSets(prev => [
      ...prev,
      { data, month: getMonth, year: getYear }
    ]);
    setPage(prev => prev + 1);
  } catch (error) {
    // 处理请求失败场景
    console.error("请求失败:", error);
  }
};

额外注意事项

  1. 日期计算bug:setMonthsBack(monthsBack + 1)是异步更新,后续直接用monthsBack会拿到旧值,导致日期计算错误,建议用monthsBack + 1直接计算或监听monthsBack变化处理。
  2. 冗余代码:getMonth已经是toString()后的字符串,无需再调用getMonth.toString(),可直接删除。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 09:46:15