React中如何让基于div实现的列导向自定义表格每行单元格高度一致
实现方案
CSS Grid 原生实现(优先推荐)
该方案无需编写额外JS逻辑,完全匹配你按列渲染的逻辑,依靠浏览器原生网格能力自动实现同行单元格等高:
- 给表格外层容器启用Grid布局,设置按列填充规则
- 列数通过CSS变量动态传入,无需硬编码
相关代码如下:
样式代码
.table-container { display: grid; grid-template-columns: repeat(var(--column-count), minmax(0, auto)); grid-auto-rows: minmax(0, auto); /* 按列填充元素,完全匹配你先渲染完一列所有行再渲染下一列的逻辑 */ grid-auto-flow: column; gap: 0; /* 可根据需要调整单元格间距 */ } .table-cell { padding: 8px 12px; border: 1px solid #e5e7eb; /* 不需要额外设置高度,网格会自动统一行高 */ }
组件TSX代码
// 假设列配置为columns,行数据总条数为rowTotal const CustomTable = ({ columns, rowTotal }: TableProps) => { return ( <div className="table-container" style={{ '--column-count': columns.length } as React.CSSProperties} > {/* 原有列渲染逻辑保持不变:先渲染第一列所有行,再依次渲染后续列 */} {columns.map(column => ( column.rows.map((cellData) => ( <div className="table-cell" key={cellData.id}> {cellData.content} </div> )) ))} </div> ) }
JS动态计算方案(兼容特殊场景)
如果业务场景无法使用Grid布局,可以通过JS计算每行最大高度实现,步骤如下:
- 给每个单元格添加
data-row-index属性标记所属行号 - 数据更新、组件挂载、窗口大小改变时,遍历所有行计算该行最大高度,统一设置给该行所有单元格
- 计算前先重置单元格高度为
auto,避免旧值影响计算结果
组件TSX代码
import { useEffect, useRef } from 'react'; const CustomTable = ({ columns, rows }: TableProps) => { const tableRef = useRef<HTMLDivElement>(null); const rowTotal = rows.length; const adjustRowHeights = () => { if (!tableRef.current) return; // 重置所有单元格高度为自动,重新计算 const allCells = tableRef.current.querySelectorAll<HTMLDivElement>('.table-cell'); allCells.forEach(cell => cell.style.height = 'auto'); // 逐行计算最大高度并统一设置 for (let rowIdx = 0; rowIdx < rowTotal; rowIdx++) { const rowCells = tableRef.current.querySelectorAll<HTMLDivElement>(`.table-cell[data-row-index="${rowIdx}"]`); let maxHeight = 0; rowCells.forEach(cell => { maxHeight = Math.max(maxHeight, cell.offsetHeight); }); rowCells.forEach(cell => { cell.style.height = `${maxHeight}px`; }); } }; // 依赖项可根据业务调整,数据变化、窗口resize时重新计算 useEffect(() => { adjustRowHeights(); const onResize = () => adjustRowHeights(); window.addEventListener('resize', onResize); return () => window.removeEventListener('resize', onResize); }, [columns, rows]); return ( <div className="table-container" ref={tableRef}> {columns.map((col, colIdx) => ( col.rows.map((cellData, rowIdx) => ( <div className="table-cell" key={`${colIdx}-${rowIdx}`} data-row-index={rowIdx} > {cellData.content} </div> )) ))} </div> ) }
注意事项
- 如果单元格包含异步加载的资源(如图片、动态渲染的富文本),需要在资源加载完成后额外调用一次
adjustRowHeights,避免高度计算偏差 - 可根据业务需要给
adjustRowHeights添加防抖,减少高频触发时的性能消耗
内容的提问来源于stack exchange,提问作者jihoon
相关产品推荐
相关产品推荐

