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> {/* 代码未写完 */} ); };
问题根源与修复方案
初始代码问题
- 提交逻辑混乱:表单
onSubmit通过条件切换回调,首次提交时isSubmit为false,只会执行handleSubmit设置错误和isSubmit状态,组件重新渲染后isSubmit变为true,第二次提交才会触发userCreate。 - 冗余状态:同时维护
name/age单独状态和formValues,容易导致数据不一致。 - 受控组件错误:input的
values属性写错,应为value,否则输入框无法正确受控。
修改后代码问题
- 逻辑完全错误:首次提交时
formErrors为空,会先设置错误;如果表单合法,validate返回空对象,后续提交仍会走设置错误分支,永远触发不了userCreate。 - 拼写错误:
setisSubmitting应为setIsSubmitting(大小写错误)。 - 代码不完整:返回的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
相关产品推荐
相关产品推荐

