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

React表单提交调用useQuery触发钩子错误,如何正确实现?

解决方案

错误原因

useQuery 是 React Hook,必须严格遵循 Hook 规则:只能在函数组件的顶层作用域或自定义 Hook 中调用,不能放在事件处理函数、循环、条件判断这类嵌套逻辑里。你把 useQuery 写在表单提交的 formSubmit 函数内,直接违反了这个规则,因此触发了错误。

正确实现:使用 useLazyQuery

Apollo Client 提供的 useLazyQuery 专门解决这类按需触发请求的场景——它不会自动执行请求,而是返回一个可手动调用的触发函数,完全符合表单提交的需求。

修改后的完整代码示例:

import { useLazyQuery } from '@apollo/client';
import { useState, SetStateAction } from 'react';
// 请确保已导入对应的GraphQL类型和查询语句
// import { GetShoeDetailsQuery, GetShoeDetailsQueryVariables } from './generated/graphql';
// import getShoeDetailsQuery from './queries/getShoeDetails';

function ShoeSearchForm() {
  const [shoe, setShoe] = useState('');
  // 初始化useLazyQuery,获取触发函数和请求状态
  const [triggerShoeQuery, { data, loading, error }] = useLazyQuery<GetShoeDetailsQuery, GetShoeDetailsQueryVariables>(
    getShoeDetailsQuery
  );

  const formSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    // 表单提交时手动触发请求,传入参数
    triggerShoeQuery({
      variables: {
        name: String(shoe),
      },
    });
  };

  return (
    <form onSubmit={formSubmit}>
      <input
        type="text"
        value={shoe}
        onChange={(e: { target: { value: SetStateAction<string> } }) => {
          setShoe(e.target.value);
        }}
        placeholder="输入鞋款名称"
      />
      <button type="submit">查询详情</button>

      {/* 可选:添加状态反馈 */}
      {loading && <p>加载中...</p>}
      {error && <p>请求失败:{error.message}</p>}
      {data && <pre>{JSON.stringify(data, null, 2)}</pre>}
    </form>
  );
}

关键细节说明

  • useLazyQuery 返回一个数组:第一个元素是触发请求的函数(示例中命名为 triggerShoeQuery),第二个元素包含请求状态(data/loading/error),结构和 useQuery 完全一致。
  • 修正了原代码的语法错误:比如 input 的 onChange 是属性,需用 onChange={...} 而非 onChange: ...;表单提交函数需接收事件参数 e 并声明类型。
  • 给 input 绑定了 value 属性,形成受控组件,避免 React 控制台警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:08:28