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

React中useForm的handleSubmit调用sendData报错求助

解决react-hook-form中handleSubmit使用错误及机制说明

原本有一个可正常向JSON文件创建新记录的sendData函数,运行一切正常。但添加useForm结合yup校验器后,在

标签的onSubmit属性中使用handleSubmit(sendData(), onSubmit)时出现错误,功能无法正常运行。需要了解handleSubmit的工作机制并解决问题。

handleSubmit工作机制

  • handleSubmit是react-hook-form的核心函数,作用是接管表单的提交流程:
    1. 自动阻止表单默认提交行为(无需手动写event.preventDefault())
    2. 触发yup校验逻辑
    3. 校验通过时,调用第一个参数(成功回调函数),并将校验后的表单数据作为参数传入该函数
    4. 校验不通过时,调用第二个可选参数(失败回调函数),传入错误信息
  • 注意:传给handleSubmit的必须是函数引用,不能是函数调用的结果(比如不能写sendData(),要写sendData)

错误原因分析

  1. 错误调用handleSubmit:handleSubmit(sendData(), onSubmit)中,sendData()是直接执行函数,导致组件渲染时就触发了sendData,而且handleSubmit接收的是sendData的返回值(undefined),不是可执行的函数,提交时自然报错。
  2. 重复维护表单状态:手动用useState维护details状态,同时又用react-hook-form的register,两者状态不同步,既冗余又容易出问题——react-hook-form本身会自动管理表单状态,不需要手动维护。

修复后的代码

import React, { useState } from 'react';
import { useForm } from 'react-hook-form';
import { useNavigate } from 'react-router-dom';
import Confirmation from './Confirmation';
import * as yup from 'yup';
import { yupResolver } from '@hookform/resolvers/yup';

const schema = yup.object().shape({
    name: yup.string().required('姓名不能为空'),
    age: yup.number().positive('年龄必须为正数').required('年龄不能为空'),
    salary: yup.number().positive('薪资必须为正数').required('薪资不能为空'),
    email: yup.string().email('请输入合法邮箱').required('邮箱不能为空'),
}).required();

export default function LogIn() {
  const { register, handleSubmit, formState: { errors } } = useForm({
    resolver: yupResolver(schema),
  });

  const navigate = useNavigate();
  const [show, setShow] = useState(false);

  // 接收react-hook-form传递的校验后的数据
  const sendData = async (data) => {
    const res = await fetch("你隐藏的接口地址", {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data) // 直接用校验后的data
    });

    navigate("/main");
  };

  const onSubmitFailed = (errors) => {
    console.log('校验失败:', errors);
  };

  return (
    <div>
      {show && <Confirmation show={show} setShow={setShow} />}
      <div className="form-center">
        <h1>填写基本信息</h1>
        {/* 正确传递函数引用给handleSubmit */}
        <form onSubmit={handleSubmit(sendData, onSubmitFailed)}>
          <div className="form-controll">
            <input 
              type="text" 
              {...register('name')} 
              placeholder="Name" 
            />
            {errors.name && <p>{errors.name.message}</p>}

            <input 
              type="number" 
              {...register('age')}  
              placeholder="Age"
            />
            {errors.age && <p>{errors.age.message}</p>}

            <input 
              type="number" 
              {...register('salary')}  
              placeholder="Salary in $"
            />
            {errors.salary && <p>{errors.salary.message}</p>}

            <input 
              type="email" 
              {...register('email')} 
              placeholder="Email"
            />
            {errors.email && <p>{errors.email.message}</p>}
          </div>

          <div className="forgot">
            Don't want to share data?<br></br>
            <button type="button" onClick={() => setShow(true)}>Ghost mode</button>
          </div>

          <div className="btn">
            <input type='submit' value='Go' />
          </div>
        </form>
      </div>
    </div>
  );
}

关键修复点

  • 移除了手动维护的details状态,直接使用react-hook-form传递的校验后的数据
  • 将handleSubmit(sendData(), onSubmit)改为handleSubmit(sendData, onSubmitFailed),传递函数引用而非调用结果
  • 移除了input上的onChange事件,register会自动更新表单状态
  • 给yup规则添加了自定义错误提示,提升用户体验
  • 给"Ghost mode"按钮添加了type="button",避免触发表单提交

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 06:16:08