You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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容器,错误表现为页面直接显示这些标签字符串,而非预期的分组布局。


问题原因

  1. JSX中直接返回字符串形式的HTML标签,React会将其视为文本节点,不会解析为DOM元素;
  2. 当前代码循环时始终渲染squares[0]和handleClick(0),没有使用当前循环的index,导致所有Square组件内容重复;
  3. 用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 03:04:49