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

React表单需两次提交才触发POST,修改后无法提交求助

问题:React表单需两次提交才触发Axios POST请求,修改后完全无法提交

我用axios实现创建用户的POST请求,React表单其他功能正常,但必须连续提交两次才触发POST请求,首次提交无响应。尝试按@DBS的方案修改后,表单彻底无法提交了。以下是初始代码和修改后的代码,求排查:

初始代码

import { useState } from 'react';

const UserCreateForm = () => {
  const [name, setName] = useState("");
  const [age, setAge] = useState("");
  const initialValues = {
    name: "",
    age: "",
  };
  const [formValues, setFormValues] = useState(initialValues);
  const [formErrors, setFormErrors] = useState({});
  const [isSubmit, setIsSubmit] = useState(false);

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormValues({ ...formValues, [name]: value });
  };

  const handleSubmit = (e) => {
    setFormErrors(validate(formValues));
    setIsSubmit(true);
  };

  const validate = (values) => {
    const errors = {};
    if (!values.name) {
      errors.name = "Name is required";
    }
    if (!values.age) {
      errors.age = "Age is required";
    }
    return errors;
  };

  const userCreate = async () => {
    await api.post("/createuser", {
      name,
      age,
    });
  };

  return (
    <div class="container">
      <Form
        onSubmit={
          Object.keys(formErrors).length === 0 && isSubmit
            ? userCreate
            : handleSubmit
        }
      >
        <Form.Field>
          <label>Name</label>
          <input
            name="name"
            onChange={(e) => {
              setName(e.target.value);
              handleChange(e);
            }}
            values={formValues.name}
          />
          <span className="error-message">{formErrors.name}</span>
        </Form.Field>
        <Form.Field>
          <label>Age</label>
          <input
            name="age"
            onChange={(e) => {
              setAge(e.target.value);
              handleChange(e);
            }}
            values={formValues.age}
          />
          <p className="error-message">{formErrors.age}</p>
        </Form.Field>
        <Button type="submit">Submit</Button>
      </Form>
    </div>
  );
};

修改后的代码

import { useState } from 'react';

const UserCreateForm = () => {
  const [name, setName] = useState("");
  const [age, setAge] = useState("");
  const initialValues = {
    name: "",
    age: "",
  };
  const [formValues, setFormValues] = useState(initialValues);
  const [formErrors, setFormErrors] = useState({});
  const [isSubmitting, setIsSubmitting] = useState(false);

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormValues({ ...formValues, [name]: value });
  };

  const handleSubmit = (e) => {
    if (!Object.keys(formErrors).length && !isSubmitting) {
      setFormErrors(validate(formValues));
    } else {
      userCreate();
      setisSubmitting(true);
    }
  };

  const validate = (values) => {
    const errors = {};
    if (!values.name) {
      errors.name = "Name is required";
    }
    if (!values.age) {
      errors.age = "Age is required";
    }
    return errors;
  };

  const userCreate = async () => {
    await api.post("/createuser", {
      name,
      age,
    });
  };

  return (
    <div class="container">
      <Form
        onSubmit={handleSubmit}
      >
        <Form.Field>
          <label>Name</label>
          <input
            name="name"
            onChange={(e) => {
              setName(e.target.value);
              handleChange(e);
            }}
            values={formValues.name}
          />
          <span className="error-message">{formErrors.name}</span>
        </Form.Field>
        <Form.Field>
          <label>Age</label>
          <input
            name="age"
            onChange={(e) => {
              setAge(e.target.value);
              handleChange(e);
            }}
            values={formValues.age}
          />
          <p className="error-message">{formErrors.age}</p>
        {/* 代码未写完 */}
  );
};

问题根源与修复方案

初始代码问题

  1. 提交逻辑混乱:表单onSubmit通过条件切换回调,首次提交时isSubmit为false,只会执行handleSubmit设置错误和isSubmit状态,组件重新渲染后isSubmit变为true,第二次提交才会触发userCreate。
  2. 冗余状态:同时维护name/age单独状态和formValues,容易导致数据不一致。
  3. 受控组件错误:input的values属性写错,应为value,否则输入框无法正确受控。

修改后代码问题

  1. 逻辑完全错误:首次提交时formErrors为空,会先设置错误;如果表单合法,validate返回空对象,后续提交仍会走设置错误分支,永远触发不了userCreate。
  2. 拼写错误:setisSubmitting应为setIsSubmitting(大小写错误)。
  3. 代码不完整:返回的JSX未闭合,导致组件无法渲染。

正确修复代码

import { useState } from 'react';

const UserCreateForm = () => {
  const initialValues = {
    name: "",
    age: "",
  };
  const [formValues, setFormValues] = useState(initialValues);
  const [formErrors, setFormErrors] = useState({});
  const [isSubmitting, setIsSubmitting] = useState(false);

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormValues(prev => ({ ...prev, [name]: value }));
  };

  const validate = (values) => {
    const errors = {};
    if (!values.name.trim()) {
      errors.name = "Name is required";
    }
    if (!values.age.trim()) {
      errors.age = "Age is required";
    }
    return errors;
  };

  const userCreate = async () => {
    try {
      setIsSubmitting(true);
      await api.post("/createuser", formValues);
      // 请求成功后重置表单
      setFormValues(initialValues);
      alert("用户创建成功");
    } catch (err) {
      console.error("创建用户失败:", err);
      alert("创建用户失败,请重试");
    } finally {
      setIsSubmitting(false);
    }
  };

  const handleSubmit = (e) => {
    e.preventDefault(); // 阻止表单默认刷新行为
    const errors = validate(formValues);
    setFormErrors(errors);
    if (Object.keys(errors).length === 0) {
      userCreate();
    }
  };

  return (
    <div className="container">
      <form onSubmit={handleSubmit}>
        <div className="Form.Field">
          <label>Name</label>
          <input
            name="name"
            onChange={handleChange}
            value={formValues.name}
            disabled={isSubmitting}
          />
          {formErrors.name && <span className="error-message">{formErrors.name}</span>}
        </div>
        <div className="Form.Field">
          <label>Age</label>
          <input
            name="age"
            onChange={handleChange}
            value={formValues.age}
            disabled={isSubmitting}
          />
          {formErrors.age && <p className="error-message">{formErrors.age}</p>}
        </div>
        <button type="submit" disabled={isSubmitting}>
          {isSubmitting ? "提交中..." : "Submit"}
        </button>
      </form>
    </div>
  );
};

export default UserCreateForm;

关键修复点

  • 移除冗余的name/age状态,统一用formValues管理表单数据。
  • 修正input的values为value,确保输入框受控。
  • 在handleSubmit中直接完成验证+提交逻辑,无需依赖额外状态切换。
  • 添加e.preventDefault()阻止表单默认刷新行为。
  • 增加isSubmitting状态防止重复提交,并给用户提交中反馈。
  • 使用函数式更新setFormValues,确保状态基于最新值更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 18:01:25