React问题:变量被渲染为文本而非HTML标签
React循环生成分组DOM时标签被解析为文本的问题
我写了个函数,想给数组里每3个元素前后分别套上带board-row类的<div>标签,当前代码如下:
const board_thing = squares.map((item, index) => { return ( <> {index % 3 === 0 ? "<div className='board-row'>" : ''} <Square value={squares[0]} onSquareClick={() => handleClick(0)}/> {index % 3 === 2 ? '</div>' : ''} </> ) })
期望实现的输出结构是:
<div className='board-row'> <Square value={squares[0]} onSquareClick={() => handleClick(0)}/> <Square value={squares[1]} onSquareClick={() => handleClick(1)}/> <Square value={squares[2]} onSquareClick={() => handleClick(2)}/> </div> <div className='board-row'> <Square value={squares[3]} onSquareClick={() => handleClick(3)}/> <Square value={squares[4]} onSquareClick={() => handleClick(4)}/> <Square value={squares[5]} onSquareClick={() => handleClick(5)}/> </div> <div className='board-row'> <Square value={squares[6]} onSquareClick={() => handleClick(6)}/> <Square value={squares[7]} onSquareClick={() => handleClick(7)}/> <Square value={squares[8]} onSquareClick={() => handleClick(8)}/> </div>
但实际运行时,<div className='board-row'>和</div>被当成纯文本显示在页面上,没有被解析成DOM容器,错误表现为页面直接显示这些标签字符串,而非预期的分组布局。
问题原因
- JSX中直接返回字符串形式的HTML标签,React会将其视为文本节点,不会解析为DOM元素;
- 当前代码循环时始终渲染
squares[0]和handleClick(0),没有使用当前循环的index,导致所有Square组件内容重复; - 用map循环插入不完整的开/闭合标签,会造成DOM结构碎片化,不符合React的渲染规则。
解决方案
先将原数组按每3个元素分组,再逐层循环生成完整的DOM结构:
// 方法1:用for循环分割数组 const groupedSquares = []; for (let i = 0; i < squares.length; i += 3) { groupedSquares.push(squares.slice(i, i + 3)); } const board_thing = groupedSquares.map((row, rowIndex) => ( <div key={rowIndex} className='board-row'> {row.map((value, colIndex) => { const squareIndex = rowIndex * 3 + colIndex; return ( <Square key={squareIndex} value={value} onSquareClick={() => handleClick(squareIndex)} /> ); })} </div> ));
或者用reduce方法分组:
// 方法2:用reduce分割数组 const groupedSquares = squares.reduce((acc, curr, index) => { const groupIdx = Math.floor(index / 3); acc[groupIdx] = [...(acc[groupIdx] || []), curr]; return acc; }, []); // 后续渲染代码同方法1
说明
- 先将原数组分割为多个长度为3的子数组,每个子数组对应一行内容;
- 外层循环每个子数组,渲染带
board-row类的完整<div>容器; - 内层循环子数组元素,通过
rowIndex * 3 + colIndex计算原数组的索引,确保value和点击事件参数正确; - 给每个循环元素添加唯一
key,符合React列表渲染的性能优化要求。
内容的提问来源于stack exchange,提问作者rexbrandy
相关产品推荐
相关产品推荐

