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

如何解决React中useQuery钩子无效调用错误(点击事件场景)

问题分析

错误根源很明确:你封装的getResend方法内部用了useQuery这个React Hook,而你在Chip的点击事件回调里调用它——回调属于组件内部的嵌套函数,并非函数组件的顶层作用域,完全违反了React Hook的调用规则(Hooks必须在函数组件顶层或自定义Hook顶层调用)。

实现方案

针对“点击Chip触发查询”的需求,给你两种常用可行的解决办法:

方案一:用useQuery的enabled参数控制触发

在组件顶层声明useQuery,通过状态变量控制查询是否执行,点击Chip时更新状态触发查询。

示例代码:

import { useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import Chip from '@mui/material/Chip';

// 把纯数据请求逻辑抽出来,不要在这里用Hook
const fetchResendData = async () => {
  const res = await fetch('/your-resend-api');
  if (!res.ok) throw new Error('请求失败');
  return res.json();
};

function YourComponent() {
  // 状态:控制查询是否触发
  const [triggerFetch, setTriggerFetch] = useState(false);

  // 组件顶层调用useQuery,enabled控制是否执行
  const { data, isLoading, refetch } = useQuery({
    queryKey: ['resend-data'],
    queryFn: fetchResendData,
    enabled: triggerFetch, // 初始不执行,只有triggerFetch为true时触发
    retry: false // 可选,避免自动重试
  });

  const handleChipClick = () => {
    // 如果只需要触发一次,更新状态即可
    setTriggerFetch(true);
    // 如果需要重复点击都触发,直接调用refetch更方便
    // refetch();
  };

  return (
    <>
      <Chip label="重新发送" onClick={handleChipClick} />
      {isLoading && <span>加载中...</span>}
      {data && <div>返回数据:{JSON.stringify(data)}</div>}
    </>
  );
}

方案二:用queryClient.fetchQuery手动触发

如果不想在组件顶层声明useQuery,可以直接通过QueryClient的fetchQuery方法在点击事件里手动发起查询,这种方式不属于Hook调用,不受顶层规则限制。

示例代码:

import { useQueryClient } from '@tanstack/react-query';
import Chip from '@mui/material/Chip';

function YourComponent() {
  const queryClient = useQueryClient();

  const handleChipClick = async () => {
    try {
      // 手动发起查询
      const data = await queryClient.fetchQuery({
        queryKey: ['resend-data'],
        queryFn: async () => {
          const res = await fetch('/your-resend-api');
          if (!res.ok) throw new Error('请求失败');
          return res.json();
        },
        staleTime: 0 // 确保每次都请求最新数据
      });
      // 拿到数据后做后续处理
      console.log('查询结果:', data);
    } catch (err) {
      // 处理错误
      console.error('请求出错:', err);
    }
  };

  return <Chip label="重新发送" onClick={handleChipClick} />;
}
额外提醒

如果你的getResend是用来提交修改类请求(比如POST),更适合用useMutation而不是useQuery——useMutation本身就提供了mutate方法,专门用来手动触发修改操作,完全适配点击触发的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 05:02:47