React多步骤表单axios POST请求必填字段报错问题解决
解决React多步骤表单axios POST提交时的必填字段错误
问题根源
- 字段命名不匹配:后端返回的错误提示是
first_name和last_name必填,但你的表单state里用的是firstName和lastName(驼峰命名),axios提交时会直接把state的key作为参数名传给后端,导致后端无法识别这两个字段,因此判定为未填写。 - HTML
required属性未生效:你给输入框加了required,但当前的Next按钮是自定义的onClick事件切换步骤,并非触发表单的submit事件,而浏览器默认的表单验证只会在submit事件触发时生效,所以这个属性起不到验证作用。
解决方案
1. 统一前后端字段命名
有两种方式处理:
- 方式一:直接修改state的key为后端期望的下划线命名:
const [formData, setFormData] = useState({ first_name: "", last_name: "", email: "", password: "", password_confirm: "", });
同时修改输入框的name属性对应:
<input type="text" name="first_name" value={formData.first_name} onChange={handleChange} /> <!-- lastName同理改成last_name -->
- 方式二:提交时转换字段名,保持前端驼峰命名:
在submitData函数里,把formData转换为后端需要的格式:
const submitData = async () => { try { // 转换字段名适配后端 const submitPayload = { first_name: formData.firstName, last_name: formData.lastName, email: formData.email, password: formData.password, password_confirm: formData.password_confirm, }; const response = await axios.post(url, submitPayload); console.log(response.data); } catch (error) { console.error(error); } };
2. 手动验证步骤输入
修改goToNextStep函数,根据当前步骤做字段验证,确保必填字段填写后再跳转:
const goToNextStep = () => { // 步骤1验证姓名 if (currentStep === 1) { if (!formData.firstName.trim() || !formData.lastName.trim()) { alert("请填写完整姓名"); return; } } // 步骤2验证邮箱和密码 if (currentStep === 2) { if (!formData.email.trim() || !formData.password.trim() || !formData.password_confirm.trim()) { alert("请填写邮箱和密码"); return; } // 额外添加密码匹配验证 if (formData.password !== formData.password_confirm) { alert("两次密码输入不一致"); return; } } setCurrentStep((prevState) => prevState + 1); };
修改后的完整代码示例
import React, { useState, useEffect } from "react"; import axios from "axios"; const url = "http://34.89.133.245/api/auth/register/"; export function Registr() { const [formData, setFormData] = useState({ firstName: "", lastName: "", email: "", password: "", password_confirm: "", }); const [currentStep, setCurrentStep] = useState(1); const handleChange = (event) => { const { name, value } = event.target; setFormData((prevState) => ({ ...prevState, [name]: value, })); }; const handleSubmit = (event) => { event.preventDefault(); }; const goToNextStep = () => { // 步骤1验证 if (currentStep === 1) { if (!formData.firstName.trim() || !formData.lastName.trim()) { alert("请填写完整姓名"); return; } } // 步骤2验证 if (currentStep === 2) { if (!formData.email.trim() || !formData.password.trim() || !formData.password_confirm.trim()) { alert("请填写邮箱和密码"); return; } if (formData.password !== formData.password_confirm) { alert("两次密码输入不一致"); return; } } setCurrentStep((prevState) => prevState + 1); }; const goToPreviousStep = () => { setCurrentStep((prevState) => prevState - 1); }; useEffect(() => { const submitData = async () => { try { // 转换字段名适配后端 const submitPayload = { first_name: formData.firstName, last_name: formData.lastName, email: formData.email, password: formData.password, password_confirm: formData.password_confirm, }; const response = await axios.post(url, submitPayload); console.log(response.data); } catch (error) { console.error(error); } }; if (currentStep === 3) { submitData(); } }, [currentStep, formData]); const renderStep1 = () => { return ( <div> <label> First Name: <input type="text" name="firstName" value={formData.firstName} onChange={handleChange} /> </label> <br /> <label> Last Name: <input type="text" name="lastName" value={formData.lastName} onChange={handleChange} /> </label> <br /> <button onClick={goToNextStep}>Next</button> </div> ); }; const renderStep2 = () => { return ( <div> <label> Email: <input type="email" name="email" value={formData.email} onChange={handleChange} /> </label> <br /> <label> Password: <input type="password" name="password" value={formData.password} onChange={handleChange} /> </label> <br /> <br /> <label> Password Confirm: <input type="password" name="password_confirm" value={formData.password_confirm} onChange={handleChange} /> </label> <br /> <button onClick={goToPreviousStep}>Previous</button> <button onClick={goToNextStep}>OK</button> </div> ); }; const renderStep3 = () => { return ( <div> <p>Thank you for registering!</p> </div> ); }; return ( <form onSubmit={handleSubmit}> {currentStep === 1 && renderStep1()} {currentStep === 2 && renderStep2()} {currentStep === 3 && renderStep3()} </form> ); }
内容的提问来源于stack exchange,提问作者Bale
相关产品推荐
相关产品推荐

