React组件Props传递异常:复用表单无法渲染且提交失效
React复用表单组件的Props传递问题
相关代码
StaffForm.js
import React from 'react' import { Link } from 'react-router-dom'; const StaffForm = ({handleSubmit},props) => { // console.log(props); const title = props.title; const link =props.link; return ( <section> <div class="Employewrapper"> <div class="title"> {title} registration </div> <form class="form" onSubmit={handleSubmit} encType='multipart/form-data'> <div class="inputfield"> <label>First Name</label> <input required type="text" class="input" name='first_name'/> </div> <div class="inputfield"> <label>Last Name</label> <input required type="text" class="input" name='last_name'/> </div> <div class="inputfield"> <label>Email</label> <input required type="email" class="input" name='email'/> </div> <div class="inputfield"> <label>Password</label> <input required type="password" class="input" name='password'/> </div> <div class="inputfield"> <label>Confirm password</label> <input required type="password" class="input" name='confirm_password'/> </div> <div class="inputfield"> <label>Phone</label> <input required type="tel" class="input" name='phone'/> </div> <div class="inputfield"> <label for="file">Profile Picture</label> <input required type="file" id="file" accept="image/*" class="input" name='profile_picture'/> </div> <div class="inputfield"> <label>Birthdate</label> <input required type="date" class="input" name='birthdate'/> </div> <div class="inputfield"> <label for="file">Id Card</label> <input required type="file" id="file" accept="image/*" class="input" name='identification_card'/> </div> <div class="inputfield"> <input required type="submit" class="btn" /> </div> <Link to={link} className='btn'>Back {title}</Link> </form> </div> </section> ) } export default StaffForm;
DeliveryForm.js
import React from 'react' import { Link } from 'react-router-dom'; import axios from 'axios'; import StaffForm from '../../Components/StaffForm'; import "../../Assets/styles/button.css" const DeliveryForm = () => { const url = 'http://127.0.0.1:8000/staff/delivery/'; const handleSubmit = (event)=>{ event.preventDefault(); const data = { "user": { "first_name": event.target.first_name.value, "last_name": event.target.last_name.value, "email": event.target.email.value, "password": event.target.password.value, "confirm_password": event.target.confirm_password.value, "phone": event.target.phone.value }, "profile_picture": event.target.profile_picture.files[0], "birthdate": event.target.birthdate.value, "identification_card": event.target.identification_card.files[0] } axios.request({ method: 'post', headers: { "Content-Type": "multipart/form-data", }, url, data }).then(res => { console.log(res) }) } return ( <> <StaffForm handleSubmit={handleSubmit} title="Delivery" link="/Delivery"/> </> ) } export default DeliveryForm
问题描述
我有一个需要复用的表单组件,要用于3个不同的API接口,只有title和link属性存在差异。按常规方式传递Props时页面无法渲染,移除Props则恢复正常;调换handleSubmit与Props的位置后,能读取到Props但表单无法提交。
解决方案
1. 修复Props传递错误
问题核心是StaffForm组件的参数解构写法错误,React组件的所有props都包含在第一个参数对象里,你原来的写法把第一个参数解构出handleSubmit,第二个参数当成props,这完全不符合React的组件参数规则。
改成以下两种写法之一即可:
写法一:直接解构所有需要的props
const StaffForm = ({ handleSubmit, title, link }) => { return ( // 原组件内容不变,直接使用title和link <section> <div class="Employewrapper"> <div class="title"> {title} registration </div> {/* ... 其余表单内容 */} <Link to={link} className='btn'>Back {title}</Link> </div> </section> ) }
写法二:接收完整props对象再取值
const StaffForm = (props) => { const { handleSubmit, title, link } = props; // 或者用 const handleSubmit = props.handleSubmit; const title = props.title; const link = props.link; return ( // 原组件内容不变 <section> {/* ... 组件内容 */} </section> ) }
2. 修复Multipart/form-data请求错误
你的axios请求直接传递普通对象处理文件上传是错误的,必须用FormData来包装数据,同时不需要手动设置Content-Type,axios会自动处理:
修改DeliveryForm中的handleSubmit函数:
const handleSubmit = (event) => { event.preventDefault(); const formData = new FormData(event.target); // 构造嵌套的user对象并转为JSON字符串(适配后端接口结构) const user = { first_name: formData.get('first_name'), last_name: formData.get('last_name'), email: formData.get('email'), password: formData.get('password'), confirm_password: formData.get('confirm_password'), phone: formData.get('phone') }; formData.append('user', JSON.stringify(user)); // 发送请求,axios自动处理multipart/form-data的请求头 axios.post(url, formData) .then(res => console.log(res)) .catch(err => console.error(err)); }
内容的提问来源于stack exchange,提问作者Abigiya Terefe
相关产品推荐
相关产品推荐

