React组件中动态生成方格并添加行号
问题背景
在开发React应用时,我们经常需要动态生成网格布局。本文将介绍如何在React组件中创建动态方格,并为每行添加行号。
实现思路
- 使用CSS Grid布局创建方格矩阵
- 通过JavaScript数组动态生成方格数量
- 利用CSS计数器或React状态管理行号显示
- 添加响应式设计确保在不同屏幕尺寸下的良好显示
基础实现方案
方案一:使用CSS计数器添加行号
这种方法通过CSS的counter-reset和counter-increment属性自动生成行号。
.grid-container {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 10px;
counter-reset: row-counter;
}
.grid-row {
display: contents;
}
.grid-row::before {
content: "Row " counter(row-counter);
counter-increment: row-counter;
font-weight: bold;
grid-column: 1 / -1;
margin-bottom: 5px;
}import React from 'react';
import './GridComponent.css';
const GridWithCSSCounter = ({ rows = 3, cols = 5 }) => {
return (
<div className="grid-container">
{Array.from({ length: rows }).map((_, rowIndex) => (
<div key={rowIndex} className="grid-row">
{Array.from({ length: cols }).map((_, colIndex) => (
<div key={colIndex} className="grid-item">
Cell {rowIndex + 1}-{colIndex + 1}
</div>
))}
</div>
))}
</div>
);
};
export default GridWithCSSCounter;方案二:使用React状态管理行号
这种方法通过React的state来管理行号,更加灵活可控。
import React from 'react';
import './GridComponent.css';
const GridWithReactState = ({ rows = 3, cols = 5 }) => {
const [gridData, setGridData] = React.useState([]);
React.useEffect(() => {
const generateGridData = () => {
const data = [];
for (let i = 0; i < rows; i++) {
const row = [];
for (let j = 0; j < cols; j++) {
row.push({
id: `${i}-${j}`,
value: `Cell ${i + 1}-${j + 1}`,
rowNumber: i + 1
});
}
data.push(row);
}
setGridData(data);
};
generateGridData();
}, [rows, cols]);
return (
<div className="grid-container">
{gridData.map((row, rowIndex) => (
<>
<div key={`row-${rowIndex}`} className="row-header">
Row {row[0].rowNumber}
</div>
{row.map((cell) => (
<div key={cell.id} className="grid-item">
{cell.value}
</div>
))}
</>
))}
</div>
);
};
export default GridWithReactState;配套CSS样式
.grid-container {
display: grid;
grid-template-columns: auto repeat(5, 1fr);
gap: 10px;
padding: 20px;
}
.row-header {
font-weight: bold;
background-color: #f0f0f0;
padding: 10px;
border-radius: 4px;
text-align: center;
align-self: center;
}
.grid-item {
background-color: #ffffff;
border: 1px solid #ddd;
padding: 20px;
text-align: center;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
@media (max-width: 768px) {
.grid-container {
grid-template-columns: auto repeat(2, 1fr);
}
}高级功能扩展
动态添加和删除行
我们可以扩展组件,使其支持动态添加和删除行的功能。
import React from 'react';
import './GridComponent.css';
const DynamicGrid = ({ initialRows = 3, cols = 5 }) => {
const [rows, setRows] = React.useState(initialRows);
const [gridData, setGridData] = React.useState([]);
React.useEffect(() => {
const generateGridData = () => {
const data = [];
for (let i = 0; i < rows; i++) {
const row = [];
for (let j = 0; j < cols; j++) {
row.push({
id: `${i}-${j}`,
value: `Cell ${i + 1}-${j + 1}`,
rowNumber: i + 1
});
}
data.push(row);
}
setGridData(data);
};
generateGridData();
}, [rows, cols]);
const addRow = () => {
setRows(prevRows => prevRows + 1);
};
const deleteRow = () => {
if (rows > 1) {
setRows(prevRows => prevRows - 1);
}
};
return (
<div className="dynamic-grid-wrapper">
<div className="controls">
<button onClick={addRow}>Add Row</button>
<button onClick={deleteRow} disabled={rows <= 1}>Delete Row</button>
</div>
<div className="grid-container">
{gridData.map((row, rowIndex) => (
<>
<div key={`row-${rowIndex}`} className="row-header">
Row {row[0].rowNumber}
</div>
{row.map((cell) => (
<div key={cell.id} className="grid-item">
{cell.value}
</div>
))}
</>
))}
</div>
</div>
);
};
export default DynamicGrid;添加悬停效果
.grid-item {
transition: all 0.3s ease;
}
.grid-item:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
background-color: #f8f9fa;
}
.row-header {
transition: background-color 0.3s ease;
}
.row-header:hover {
background-color: #e2e6ea;
}性能优化建议
- 对于大型网格,考虑使用虚拟滚动技术
- 使用React.memo包装网格项组件以避免不必要的重渲染
- 合理使用useCallback和useMemo钩子优化性能
- 避免在渲染函数中创建新的对象或函数
总结
本文介绍了两种在React中动态生成方格并添加行号的方法:CSS计数器方案和React状态管理方案。CSS计数器方案更简洁,适合静态网格;React状态管理方案更灵活,适合需要动态交互的场景。根据实际需求选择合适的方案,并注意性能优化,可以创建出既美观又高效的网格组件。