本文介绍如何将具有三层嵌套关系(参与者 → 分类 → 卡片)的原始数据,规范化为扁平化对象数组,并使用 rowSpan 实现语义清晰的 React 表格渲染,确保同一参与者的多分类共享单一行号与评论。
本文介绍如何将具有三层嵌套关系(参与者 → 分类 → 卡片)的原始数据,规范化为扁平化对象数组,并使用 `rowspan` 实现语义清晰的 react 表格渲染,确保同一参与者的多分类共享单一行号与评论。
在 React 应用中处理多层级业务数据(如参与者、其下属多个分类、每个分类下若干卡片)时,直接基于深度嵌套数组渲染表格易导致结构混乱、可维护性差。最佳实践是先归一化数据结构,再声明式渲染。
原始 participant_data 是混合类型数组(字符串、嵌套数组),不利于 React 的 map 和 key 管理。应转换为统一对象数组,例如:
const sortedData = [ { no: '#1', category: 'not set #0', cards: ['card1', 'A very large title title tile1', /* ... */], comment: 'comment ' }, { no: '#1', category: 'not set #1', cards: ['A very large title title tile2', 'A very large title title tile9'], comment: 'comment ' }, { no: '#1', category: 'name1', cards: ['card1', 'A very large title title tile1', /* ... */], comment: 'comment ' }, // ... 其他条目];
该结构明确分离了四维信息:no(参与者标识)、category(分类名)、cards(卡片列表)、comment(全局备注),为表格渲染奠定坚实基础。
利用 <td rowSpan> 合并同一参与者的垂直单元格,避免重复显示 participant 和 comment。关键点在于:
完整 JSX 示例:
<table className="min-w-full border-collapse"> <thead> <tr> <th className="border px-3 py-2">Participant</th> <th className="border px-3 py-2">Category</th> <th className="border px-3 py-2">Cards</th> <th className="border px-3 py-2">Comment</th> </tr> </thead> <tbody> {sortedData.map((item, index, array) => ( <tr key={`${item.no}-${item.category}-${index}`}> {/* Participant column — only render on first occurrence */} {index === 0 || item.no !== array[index - 1].no ? ( <td rowSpan={array.filter(el => el.no === item.no).length} className="border px-3 py-2 font-medium"> {item.no} </td> ) : null} {/* Category column — always render */} <td className="border px-3 py-2">{item.category}</td> {/* Cards column — render as bullet list for readability */} <td className="border px-3 py-2"> {Array.isArray(item.cards) ? ( <ul className="list-disc list-inside m-0 p-0 text-sm"> {item.cards.map((card, i) => ( <li key={i} className="whitespace-normal break-words">{card}</li> ))} </ul> ) : ( String(item.cards) )} </td> {/* Comment column — only render on first occurrence */} {index === 0 || item.no !== array[index - 1].no ? ( <td rowSpan={array.filter(el => el.no === item.no).length} className="border px-3 py-2 text-gray-600"> {item.comment} </td> ) : null} </tr> ))} </tbody></table>
通过结构规范化 + rowSpan 精准控制,你不仅能清晰表达“谁(Participant)→ 在哪类(Category)→ 有哪些卡(Cards)”,还能自然承载上下文备注(Comment),让复杂嵌套数据在表格中一目了然。