如何在ReactJs编辑表单中加载填充已有数据库用户记录
问题描述
我需要一个可更新用户数据(包含code、article、price、vat、status、companyid字段)的表单,要求打开编辑弹窗时,通过API获取该用户的对应数据并自动填充到输入框中,方便进行修改操作。以下是我目前的代码实现:
原组件代码
import { getUsers, editUser } from '../Service/api' import { useEffect } from 'react' const DialogEditUser = (data) => { const [RowData, SetRowData] = useState([]) const [ViewEdit, setEditShow] = useState(false) const [id, setId] = useState('') const [code, setCode] = useState('') const [article, setArticle] = useState('') const user = { id, code, article } const normalize = (v) => ({ code: String(v.code), article: String(v.article), }) const handleEditShow = () => { setEditShow(true) } const handleEditClose = () => { setEditShow(false) } const handleEdit = () => { editUser(data.props, normalize(user)) } useEffect(() => { getUsers() }, []) return ( <> <CButton style={{ marginRight: '10px', color: 'info', border: 'none', boxShadow: `2px 2px 9px -3px rgba(0,0,0,0.6)`, }} onClick={() => handleEditShow(SetRowData(data), setId(data.id))} > Edit </CButton> <CModal visible={ViewEdit} onClose={handleEditClose} backdrop={'static'} keyboard={false} portal={false} > <CModalHeader> <CModalTitle>Edit User:</CModalTitle> </CModalHeader> <CModalBody> <CForm> <CFormInput type="text" id="exampleFormControlInput1" label="Code :" placeholder="Enter Code" text=" " aria-describedby="exampleFormControlInputHelpInline" name="code" onChange={(e) => setCode(e.target.value)} defaultValue={RowData.code} /> <CFormInput type="text" id="exampleFormControlInput2" label="Article :" placeholder="Enter Article" text=" " aria-describedby="exampleFormControlInputHelpInline" name="article" onChange={(e) => setArticle(e.target.value)} defaultValue={RowData.article} /> <CModalFooter> <CButton color="secondary" onClick={() => setEditShow(false)}> Cancel </CButton> <CButton color="primary" onClick={() => { handleEdit() setEditShow(false) }} > Update </CButton> </CModalFooter> </CModal> </> ) } export default DialogEditUser
原API代码(src/Service/api.js)
//... export const getUsers = async (id) => { id = id || '' try { return await axios.get(`${baseURL}`, config) } catch (error) { console.log('Error while calling getUsers api ', error) } } //...
修正方案
1. 修复API函数
修改getUsers,让它根据传入的id获取单个用户数据:
// src/Service/api.js export const getUsers = async (id) => { try { // 传入id则获取单个用户,否则获取用户列表 const url = id ? `${baseURL}/${id}` : baseURL; const response = await axios.get(url, config); return response.data; // 直接返回响应体数据,方便组件使用 } catch (error) { console.log('Error while calling getUsers api ', error); throw error; // 抛出错误,让组件可以处理异常 } }
2. 修正组件逻辑
调整props接收、状态管理、弹窗打开时的数据获取逻辑:
import { getUsers, editUser } from '../Service/api'; import { useState, useEffect } from 'react'; // 解构接收父组件传入的用户数据 const DialogEditUser = ({ user }) => { const [isEditOpen, setIsEditOpen] = useState(false); // 用单个对象统一管理所有表单字段状态 const [formData, setFormData] = useState({ id: '', code: '', article: '', price: '', vat: '', status: '', companyid: '' }); // 弹窗打开时,根据用户id获取数据并填充表单 useEffect(() => { if (isEditOpen && user?.id) { const fetchUserData = async () => { try { const userDetail = await getUsers(user.id); setFormData({ id: userDetail.id, code: userDetail.code || '', article: userDetail.article || '', price: userDetail.price || '', vat: userDetail.vat || '', status: userDetail.status || '', companyid: userDetail.companyid || '' }); } catch (error) { console.error('获取用户详情失败:', error); } }; fetchUserData(); } }, [isEditOpen, user?.id]); const handleEditShow = () => { setIsEditOpen(true); }; const handleEditClose = () => { setIsEditOpen(false); }; // 统一处理所有输入框的变化 const handleInputChange = (e) => { const { name, value } = e.target; setFormData(prev => ({ ...prev, [name]: value })); }; const handleEdit = async () => { try { await editUser(formData.id, formData); // 可在此添加成功提示,或通知父组件更新用户列表 } catch (error) { console.error('更新用户数据失败:', error); } }; return ( <> <CButton style={{ marginRight: '10px', color: 'info', border: 'none', boxShadow: `2px 2px 9px -3px rgba(0,0,0,0.6)` }} onClick={handleEditShow} > Edit </CButton> <CModal visible={isEditOpen} onClose={handleEditClose} backdrop={'static'} keyboard={false} portal={false} > <CModalHeader> <CModalTitle>Edit User:</CModalTitle> </CModalHeader> <CModalBody> <CForm> <CFormInput type="text" label="Code:" placeholder="Enter Code" name="code" onChange={handleInputChange} value={formData.code} className="mb-3" /> <CFormInput type="text" label="Article:" placeholder="Enter Article" name="article" onChange={handleInputChange} value={formData.article} className="mb-3" /> <CFormInput type="number" label="Price:" placeholder="Enter Price" name="price" onChange={handleInputChange} value={formData.price} className="mb-3" /> <CFormInput type="number" label="VAT:" placeholder="Enter VAT" name="vat" onChange={handleInputChange} value={formData.vat} className="mb-3" /> <CFormInput type="text" label="Status:" placeholder="Enter Status" name="status" onChange={handleInputChange} value={formData.status} className="mb-3" /> <CFormInput type="text" label="Company ID:" placeholder="Enter Company ID" name="companyid" onChange={handleInputChange} value={formData.companyid} /> </CForm> </CModalBody> <CModalFooter> <CButton color="secondary" onClick={handleEditClose}> Cancel </CButton> <CButton color="primary" onClick={() => { handleEdit(); handleEditClose(); }} > Update </CButton> </CModalFooter> </CModal> </> ); }; export default DialogEditUser;
关键修正点说明
- Props接收优化:改为解构
{ user },明确接收父组件传入的用户数据,避免props层级混乱。 - 状态统一管理:用
formData对象管理所有表单字段,替代零散的状态变量,更易维护。 - 数据填充时机:在弹窗打开时触发API请求,获取对应用户数据并更新表单状态,确保打开弹窗时数据已填充。
- 受控组件实现:输入框使用
value绑定状态,而非defaultValue,保证表单数据与状态实时同步。 - API逻辑优化:
getUsers根据id请求单个用户数据,并返回响应体;添加错误抛出,让组件可以捕获并处理异常。 - 输入处理简化:用统一的
handleInputChange处理所有输入框变化,减少重复代码。
内容的提问来源于stack exchange,提问作者Darkpsinight
相关产品推荐
相关产品推荐

