React+Material Table弹窗编辑表单预填充问题求助
解决React+Material-Table编辑弹窗表单预填充失败问题
核心问题分析
你的CustomerForm组件中,formData的useState初始值仅在组件首次渲染时读取recordForEdit。当点击编辑按钮更新recordForEdit后,组件重新渲染但formData不会自动同步新数据,导致表单无法预填充。另外还有两处小bug影响功能:
showPreview里的render.result是笔误,应为x.target.resulthandleFormSubmit内的formData变量和组件state的formData重名,会覆盖原state变量
修复步骤
1. 用useEffect同步recordForEdit到formData
在CustomerForm组件中添加useEffect,监听recordForEdit的变化并同步到表单state:
import { useEffect, useState } from 'react'; const CustomerForm = ({open, onClose, recordForEdit}) => { const [formData, setFormData] = useState({ customerId: 0, customerCode: "", customerDescription: "", customerAddress: "", customerContact: "", customerSite: "", customerDistanceOffice: "", imageSrc: Img, imageFile: null, }); // 监听recordForEdit更新,同步表单数据 useEffect(() => { if (recordForEdit) { setFormData({ customerId: recordForEdit.customerId || 0, customerCode: recordForEdit.customerCode || "", customerDescription: recordForEdit.customerDescription || "", customerAddress: recordForEdit.customerAddress || "", customerContact: recordForEdit.customerContact || "", customerSite: recordForEdit.customerSite || "", customerDistanceOffice: recordForEdit.customerDistanceOffice || "", imageSrc: recordForEdit?.imageSrc || Img, imageFile: recordForEdit?.imageFile || null, }); } }, [recordForEdit, Img]); // 其余代码保持不变... }
2. 修复showPreview中的笔误
将render.result修正为x.target.result:
const showPreview = (e) => { if (e.target.files && e.target.files[0]) { let imageFile = e.target.files[0]; const reader = new FileReader(); reader.onload = (x) => { setFormData({ ...formData, imageFile, imageSrc: x.target.result, // 修正此处 }); }; reader.readAsDataURL(imageFile); } else { setFormData({ ...formData, imageFile: null, imageSrc: Img, }); } };
3. 修复handleFormSubmit的变量名冲突
重命名函数内的formData变量,避免覆盖组件state:
const handleFormSubmit = (event) => { event.preventDefault(); const form = document.querySelector('#customerForm'); const formDataFromForm = new FormData(form); // 重命名变量 formDataFromForm.append('customerId', form.customerId.value) const data = JSON.stringify(Object.fromEntries(formDataFromForm.entries())); console.log(form) api .put(`Customer/${formDataFromForm.get('customerId')}`, data) // 更新对应变量 .then((res) => { // 此处建议调用父组件的更新方法或直接关闭弹窗 onClose(); }) .catch((err) => { toast.error("Problem Updating", { position: toast.POSITION.TOP_RIGHT, }); console.log(err); }); clearForm(); };
4. 父组件初始化recordForEdit状态
确保父组件中recordForEdit初始化为null,避免首次渲染时的空值问题:
const [recordForEdit, setRecordForEdit] = useState(null);
完成以上修改后,点击编辑按钮时,recordForEdit更新会触发useEffect同步数据到表单,即可实现正确的预填充效果。
内容的提问来源于stack exchange,提问作者Gary
相关产品推荐
相关产品推荐

