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

React+TSX中TSX元素比较失败求助:原因及解决方法

问题原因与解决方法

1. JSX元素全等比较失败的原因

  • React中JSX元素是React.createElement()的语法糖,每次书写<div>...</div>都会生成新的对象引用。哪怕内容完全一致,两个JSX元素的内存地址不同,用===做全等比较时会直接判定为不相等。
  • 你用Array.fill()初始化的数组里,所有元素都是同一个JSX对象的引用,但在placeTile函数里你创建了一个新的、内容相同的JSX元素来做比较,两者引用不同,所以比较永远失败。

2. tiles[index].id返回undefined的原因

  • tiles数组存储的是虚拟DOM对象(React元素),而非真实DOM节点。虚拟DOM的属性都封装在props字段中,直接访问.id无法获取到值,正确写法是tiles[index].props.id。但这种方式并非最优解,下文会说明原因。

正确解决思路:用数据模型替代存JSX元素在state中

React的最佳实践是state存储数据,渲染阶段根据数据生成JSX,而非直接将JSX存入state。这种方式既便于状态比较,也能规避虚拟DOM引用带来的问题。

修改步骤:

  1. 定义tile的数据结构:
    type Tile = {
      type: 'filler' | 'filled';
      id: string;
      value: string;
    };
    
  2. 初始化state为数据数组:
    const initialTiles: Tile[] = Array(9).fill({
      type: 'filler',
      id: '.',
      value: '.'
    });
    const [tiles, setTiles] = useState<Tile[]>(initialTiles);
    
  3. 渲染时根据数据生成JSX:
    return (
      <div className="tile-container">
        {tiles.map((tile, index) => (
          <div
            key={index}
            className={tile.type}
            id={tile.id}
            onClick={() => placeTile(index)}
          >
            {tile.value}
          </div>
        ))}
      </div>
    );
    
  4. 修改placeTile函数,直接比较数据:
    function placeTile(index: number) {
      if (tiles[index].id === '.') {
        const updateTile = [...tiles];
        updateTile[index] = {
          type: 'filled',
          id: move,
          value: move
        };
        console.log("Filled a spot");
        setTiles(updateTile);
      } else {
        console.log("This is filled spot " + index);
      }
    }
    

其他可选比较方式(非推荐)

若因特殊需求必须存储JSX在state中,可通过比较虚拟DOM的props属性来判断:

if (tiles[index].props.id === '.' && tiles[index].props.className === 'filler') {
  // 执行填充逻辑
}

这种方式不推荐,因为虚拟DOM结构可能随需求变更,维护成本远高于直接存储数据模型。

内容的提问来源于stack exchange,提问作者Anirudh Agrawal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 22:13:18