ReactJS实现表格行内字段可编辑(除指定字段)功能的方案咨询
行内编辑功能实现方案
你可以基于现有React代码做以下改造完成需求:
1. 新增组件状态
首先在组件内新增两个状态变量,用来跟踪编辑状态和临时存储编辑数据:
// 记录当前正在编辑的行索引,null代表无编辑行 const [editingRowIndex, setEditingRowIndex] = useState<number | null>(null) // 存储当前编辑行的临时修改数据 const [editingForm, setEditingForm] = useState<Partial<Certificate>>({})
2. 改造编辑按钮点击逻辑
修改原来的编辑触发方法,点击编辑时初始化编辑状态:
const handleEdit = (certificate: Certificate, index: number) => { setEditingRowIndex(index) // 深拷贝当前行数据作为编辑初始值 setEditingForm({...certificate}) }
3. 新增保存逻辑
编写保存按钮触发的提交逻辑,提交成功后更新列表并退出编辑状态:
const handleSave = async (index: number) => { try { // 这里调用你原来的保存接口提交editingForm数据 await saveCertificateApi(editingForm) // 更新原response列表对应索引的数据,setResponse为你存储列表的状态更新方法 const newResponse = [...response] newResponse[index] = editingForm as Certificate setResponse(newResponse) // 退出编辑状态 setEditingRowIndex(null) } catch (err) { // 自行适配报错提示逻辑 console.error('保存失败', err) } }
4. 改造表格渲染逻辑
修改tbody内的行渲染代码,根据编辑状态切换单元格的展示/编辑形式,以及按钮的展示:
<tbody> {response.map((certificate: Certificate,index:number) => { const isEditing = editingRowIndex === index return ( <tr key={certificate.certificateNo}> {/* certificateNo字段永远不可编辑 */} <td>{certificate.certificateNo}</td> <td> {isEditing ? <input type="text" value={editingForm.sponser ?? ''} onChange={(e) => setEditingForm({...editingForm, sponser: e.target.value})} /> : certificate.sponser } </td> <td> {isEditing ? <input type="text" value={editingForm.protoColNo ?? ''} onChange={(e) => setEditingForm({...editingForm, protoColNo: e.target.value})} /> : certificate.protoColNo } </td> <td> {isEditing ? <input type="date" value={editingForm.startDate ?? ''} onChange={(e) => setEditingForm({...editingForm, startDate: e.target.value})} /> : certificate.startDate } </td> <td> {isEditing ? <input type="date" value={editingForm.endDate ?? ''} onChange={(e) => setEditingForm({...editingForm, endDate: e.target.value})} /> : certificate.endDate } </td> <td> {isEditing ? <input type="number" value={editingForm.noOfSubjects ?? 0} onChange={(e) => setEditingForm({...editingForm, noOfSubjects: Number(e.target.value)})} /> : certificate.noOfSubjects } </td> <td> {isEditing ? <input type="text" value={editingForm.country ?? ''} onChange={(e) => setEditingForm({...editingForm, country: e.target.value})} /> : certificate.country } </td> <td> {isEditing ? <select value={editingForm.requestStatus ?? ''} onChange={(e) => setEditingForm({...editingForm, requestStatus: e.target.value})} > {/* 这里替换成你实际的状态选项 */} <option value="PENDING">待审核</option> <option value="APPROVED">已通过</option> <option value="REJECTED">已驳回</option> </select> : certificate.requestStatus } </td> <td> <div className="btn-group mr-2"> {isEditing ? ( <button className="btn btn-sm btn-outline-primary" onClick={()=>handleSave(index)}> 保存 </button> // 如果需要取消按钮可以取消注释下方代码 /* <button className="btn btn-sm btn-outline-secondary ml-1" onClick={()=>setEditingRowIndex(null)}> 取消 </button> */ ) : ( <button className="btn btn-sm btn-outline-secondary" onClick={()=>handleEdit(certificate,index)}> <i className="bi bi-pencil"></i> </button> )} </div> </td> </tr> ) })} </tbody>
如果需要适配不同字段的输入类型,比如下拉选择、数字输入等,直接修改对应字段的输入组件即可,逻辑完全通用。
内容的提问来源于stack exchange,提问作者Shruti sharma
相关产品推荐
相关产品推荐

