React项目中Bootstrap可编辑动态成绩表格开发求助
解决React+Bootstrap成绩表格的动态数据与编辑问题
问题分析
原代码存在几个核心问题:
- 数据结构不合理:用字符串数组存储学生信息,无法承载学号、姓名、各科成绩等多字段数据
- 表格布局不规范:用div手动模拟表格列,容易出现对齐错乱,Bootstrap自带的table组件更适合这类结构化表格场景
- 编辑逻辑单一:仅支持单个字段编辑,无法满足姓名、学号等多字段编辑需求
修正方案
下面是重构后的代码,解决了上述问题,同时实现动态数据渲染、多字段编辑需求,并保证表格布局的一致性:
import React, { useState } from 'react'; function ExamMarksTable() { // 重构数据结构:每个学生对象包含所有所需字段 const [students, setStudents] = useState([ { id: 1, rollNo: "CS001", prnNo: "2023CS001", name: "张三", ese: 62, midSem: 27, prOr: 22, termWork: 23, total: 134 }, { id: 2, rollNo: "CS002", prnNo: "2023CS002", name: "李四", ese: 58, midSem: 25, prOr: 20, termWork: 21, total: 124 } ]); // 记录当前编辑的学生ID和临时编辑数据 const [editingId, setEditingId] = useState(null); const [tempStudent, setTempStudent] = useState({}); // 开启编辑模式,复制当前学生数据到临时对象 const handleEdit = (student) => { setEditingId(student.id); setTempStudent({ ...student }); }; // 保存编辑内容,更新学生列表并退出编辑模式 const handleSave = () => { setStudents(students.map(s => s.id === editingId ? tempStudent : s)); setEditingId(null); }; // 取消编辑,直接退出编辑模式 const handleCancel = () => { setEditingId(null); }; // 处理临时编辑数据的字段更新 const handleInputChange = (field, value) => { setTempStudent(prev => ({ ...prev, [field]: value })); }; return ( <div className="container-fluid mt-4"> <div className="card"> <div className="card-header bg-dark text-white fs-4 fw-bold"> CO Attainment from University Exam </div> <div className="card-body p-0"> <table className="table table-bordered table-hover align-middle"> <thead className="table-light"> <tr> <th className="text-center" style={{ width: "5%" }}>Sr.No</th> <th className="text-center" style={{ width: "10%" }}>Roll No.</th> <th className="text-center" style={{ width: "15%" }}>Prn No.</th> <th className="text-center" style={{ width: "20%" }}>Student Name</th> {/* 合并表头:各科成绩区域 */} <th colSpan="5" className="text-center"> Exam Scores (Total: 150) </th> <th className="text-center" style={{ width: "10%" }}>操作</th> </tr> <tr> <th></th> <th></th> <th></th> <th></th> <th className="text-center">ESE (70)</th> <th className="text-center">Mid Sem (30)</th> <th className="text-center">PR/OR (25)</th> <th className="text-center">Term Work (25)</th> <th className="text-center">Total</th> <th></th> </tr> </thead> <tbody> {students.map((student, index) => ( <tr key={student.id}> <td className="text-center">{index + 1}</td> {/* 学号编辑逻辑 */} <td> {editingId === student.id ? ( <input type="text" className="form-control" value={tempStudent.rollNo} onChange={(e) => handleInputChange('rollNo', e.target.value)} /> ) : ( student.rollNo )} </td> {/* PRN号编辑逻辑 */} <td> {editingId === student.id ? ( <input type="text" className="form-control" value={tempStudent.prnNo} onChange={(e) => handleInputChange('prnNo', e.target.value)} /> ) : ( student.prnNo )} </td> {/* 姓名编辑逻辑 */} <td> {editingId === student.id ? ( <input type="text" className="form-control" value={tempStudent.name} onChange={(e) => handleInputChange('name', e.target.value)} /> ) : ( student.name )} </td> {/* 成绩字段(如需编辑可参考上面的输入框逻辑) */} <td className="text-center">{student.ese}</td> <td className="text-center">{student.midSem}</td> <td className="text-center">{student.prOr}</td> <td className="text-center">{student.termWork}</td> <td className="text-center fw-bold">{student.total}</td> {/* 操作按钮组 */} <td className="text-center"> {editingId === student.id ? ( <div className="d-flex gap-2 justify-content-center"> <button className="btn btn-sm btn-success" onClick={handleSave}> 保存 </button> <button className="btn btn-sm btn-secondary" onClick={handleCancel}> 取消 </button> </div> ) : ( <button className="btn btn-sm btn-primary" onClick={() => handleEdit(student)}> 编辑 </button> )} </td> </tr> ))} </tbody> </table> </div> </div> </div> ); } export default ExamMarksTable;
关键改进点
- 数据结构优化:改用对象数组存储每个学生的完整信息,方便管理多字段数据,也便于后续从接口获取数据直接替换
- Bootstrap Table组件:使用原生table搭配Bootstrap的table类,自动处理列对齐和响应式布局,避免手动div布局的错乱问题
- 多字段编辑支持:通过
editingId标记当前编辑的学生,临时存储编辑内容,保存时批量更新学生数据 - 表头合并:使用
colSpan实现成绩区域的表头合并,完全匹配需求中的表格结构 - 操作逻辑简化:合并编辑、保存、取消逻辑,代码结构更清晰,易维护和扩展
内容的提问来源于stack exchange,提问作者Vardhaman Begani
相关产品推荐
相关产品推荐

