ReactJS中如何循环复用组件生成4x7二维网格并实现点击按钮变色
错误原因说明
你现有代码的报错是因为changeColor函数里调用getElementById时传了硬编码字符串"index",既没有使用实际传入的index变量,也没有拼接button前缀,自然找不到对应DOM元素才返回null。另外React框架本身不推荐直接操作DOM,所有视图变更都应该通过state驱动实现。
完整实现方案
1. 4x7网格布局实现
不需要手动渲染换行组件,直接用CSS Grid即可自动完成7列4行的排列,代码更简洁易维护。
2. 点击变色功能实现
用useState存储已选中的座位编号集合,点击时更新集合,渲染时根据编号是否在集合中动态设置背景色即可。
import { useState } from 'react'; const SeatBooking = () => { // 存储已选中的座位id,用Set结构方便判断存在性和增删 const [selectedSeats, setSelectedSeats] = useState(new Set()); const totalRows = 4; const colsPerRow = 7; // 生成28个座位的数组,对应4行7列 const seats = Array.from({ length: totalRows * colsPerRow }, (_, idx) => idx + 1); const toggleSeat = (seatId) => { const newSelected = new Set(selectedSeats); if (newSelected.has(seatId)) { newSelected.delete(seatId); } else { newSelected.add(seatId); } setSelectedSeats(newSelected); }; return ( <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: '10px', maxWidth: '500px', margin: '20px auto' }}> {seats.map(seatId => ( <button key={seatId} className="btn btn-danger" onClick={() => toggleSeat(seatId)} style={{ padding: '10px', borderRadius: '4px', // 动态判断背景色 backgroundColor: selectedSeats.has(seatId) ? 'green' : 'white', cursor: 'pointer' }} > {seatId} </button> ))} </div> ); }; export default SeatBooking;
如果你一定要用双重循环的写法实现,也可以按如下方式生成二维数组渲染:
const rows = Array.from({ length: 4 }, (_, rowIdx) => { return Array.from({ length: 7 }, (_, colIdx) => rowIdx *7 + colIdx +1); }); // 渲染的时候嵌套map即可 return ( <div style={{maxWidth: '500px', margin: '20px auto'}}> {rows.map((rowSeats, rowIdx) => ( <div key={rowIdx} style={{ display: 'flex', gap: '10px', marginBottom: '10px' }}> {rowSeats.map(seatId => ( <button key={seatId} className="btn btn-danger" onClick={() => toggleSeat(seatId)} style={{ padding: '10px', borderRadius: '4px', backgroundColor: selectedSeats.has(seatId) ? 'green' : 'white', cursor: 'pointer' }} > {seatId} </button> ))} </div> ))} </div> )
内容的提问来源于stack exchange,提问作者Ansh Shah
相关产品推荐
相关产品推荐

