React表格渲染问题:无法映射双数组实现同一行内嵌子行效果
解决表格子行渲染混乱的问题
看起来你现在的核心问题是把intake的行和attendance的行分开循环渲染,导致两者完全脱节,表格结构自然就乱了。毕竟每个attendance ID对应多个intake,得把它们关联起来渲染,让每个attendance的主数据和它对应的多个intake子行对齐才行。我给你具体的解决方案:
第一步:先把分散的数据整合成结构化的对象数组
你现在的data是分散的多个数组(date[]、duration[]、intake[]等),这种结构很容易出现索引对应错误,也不方便关联attendance和它的intakes。先把它们合并成每个attendance对应一个对象,里面包含所有相关数据和对应的intake数组:
// 假设你现有这些变量:attendanceIds, date, duration, module, start, topic, studentsPresent, totalStudents, intakeList(intakeList的每个元素是对应attendance的intake数组) const attendanceData = attendanceIds.map((id, index) => ({ id: id, date: date[index], duration: duration[index], module: module[index], start: start[index], topic: topic[index], studentsPresent: studentsPresent[index], totalStudents: totalStudents[index], intakes: intakeList[index] // 每个attendance对应的多个intake值 }));
第二步:用rowspan实现主行跨子行的表格结构
现在可以循环这个结构化的数组,对于每个attendance,我们让它的主数据单元格(除了intake列)跨intakes.length行,然后第一个intake和主数据放在同一行,剩下的intake单独作为子行,这样表格结构就不会乱了:
<table> <thead> <tr> <th>Intake</th> <th>Date</th> <th>Duration</th> <th>Module</th> <th>Start</th> <th>Topic</th> <th>Students Present</th> <th>Total Students</th> <th>Actions</th> </tr> </thead> <tbody> {attendanceData.map((attendance) => { const intakeCount = attendance.intakes.length; return ( <> {/* 第一行:第一个intake + 主数据(跨所有intake行) */} <tr> <th className="text-center" scope="row">{attendance.intakes[0]}</th> <td className="text-center" rowSpan={intakeCount}>{attendance.date}</td> <td className="text-center" rowSpan={intakeCount}>{attendance.duration}</td> <td className="text-center" rowSpan={intakeCount}>{attendance.module}</td> <td className="text-center" rowSpan={intakeCount}>{attendance.start}</td> <td className="text-center" rowSpan={intakeCount}>{attendance.topic}</td> <td className="text-center" rowSpan={intakeCount}>{attendance.studentsPresent}</td> <td className="text-center" rowSpan={intakeCount}>{attendance.totalStudents}</td> <td className="text-center" rowSpan={intakeCount}> <button className="button" id={attendance.id}>Details</button> </td> </tr> {/* 剩余的intake子行:只渲染intake列,其他列自动对齐 */} {attendance.intakes.slice(1).map((intake) => ( <tr key={intake}> {/* 记得加key避免React警告 */} <th className="text-center" scope="row">{intake}</th> </tr> ))} </> ); })} </tbody> </table>
为什么之前的代码会乱?
你原来的代码是先循环所有intake生成一堆单独的行,再循环attendanceIds生成另一堆行,这两部分完全没有关联,表格的列数对应不上,结构自然就崩了。现在的写法是把每个attendance的主数据和它的所有intake绑定在一起渲染,用rowspan让主数据单元格覆盖所有对应的intake行,保证表格的列对齐和结构完整。
内容的提问来源于stack exchange,提问作者Muhammad Hasan Khan
相关产品推荐
相关产品推荐

