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

React中useQuery执行4次后报错:原因及解决方法

问题原因与修复方案

问题原因

  1. 错误使用useQuery处理POST请求:React Query的useQuery是为**只读查询(GET类请求)**设计的,它会自动缓存、重试失败请求(默认重试3次),完全不适合用于修改数据的POST操作——这就是你看到请求执行4次的核心原因:1次初始请求+3次自动重试。
  2. 动态queryKey导致重复实例创建:用Math.random()生成queryKey,组件每次渲染都会生成全新的key,导致useQuery实例不断重建,进一步触发多余的请求逻辑。
  3. 异步函数返回值错误:axios请求的then回调里的data是局部变量,外层的return data实际返回的是未定义变量,导致React Query无法识别请求结果,判定请求失败并触发重试。
  4. 状态变化加剧重复请求:如果submittedExpense是组件状态,每次状态更新都会触发usePostData重新执行,结合动态queryKey,问题会更严重。

修复方案

1. 改用useMutation处理POST请求

useMutation是React Query专门为**写操作(POST/PUT/DELETE)**设计的API,替换你的自定义hook:

import { useMutation } from "@tanstack/react-query";
import axios from "axios";

const usePostData = () =>
  useMutation({
    mutationFn: async ({ endPoint, object }) => {
      const response = await axios.post("http://localhost:1337" + endPoint, object);
      console.log(response.data);
      return response.data;
    },
    onError: (err) => console.log(err)
  });

export default usePostData;

2. 调整组件调用逻辑

移除动态queryKey,直接用mutate方法触发提交:

const { mutate: postExpense } = usePostData();

const handleSubmitExpense = (e) => {
  e.preventDefault();
  postExpense({ 
    endPoint: "/api/expences", 
    object: submittedExpense 
  });
};

3. 可选:添加状态优化(提升用户体验)

利用useMutation返回的状态,实现加载禁用、错误提示:

const { mutate: postExpense, isLoading, error } = usePostData();

return (
  <form onSubmit={handleSubmitExpense}>
    {/* 表单内容 */}
    <button type="submit" disabled={isLoading}>
      {isLoading ? "提交中..." : "提交"}
    </button>
    {error && <p style={{ color: "red" }}>提交失败:{error.message}</p>}
  </form>
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 20:55:13