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

React TypeScript中使用innerHTML报错Cannot set property 'innerHTML' of null

报错原因
  • 你调用callGames的时机早于newBet组件的挂载时机,document.getElementById('bets-container-lotos')还找不到对应DOM节点,返回结果为null,对其赋值innerHTML自然触发类型报错
  • 就算能拿到对应DOM节点,用innerHTML插入<Loto>这类React组件标签的写法也完全无效:原生DOM不识别React组件语法,插入的内容只会被当作普通字符串,不会渲染为实际的Loto组件,后续通过id查找对应节点也必然返回null
  • 你这套原生JS直接操作DOM的写法完全不符合React的声明式渲染逻辑,属于思路层面的错误,React本身就不推荐开发者直接操作DOM
正确改造方案

完全抛弃原来的innerHTML和手动DOM操作思路,直接用React的原生渲染逻辑实现需求,不需要额外维护callGames函数:

// 先定义gamesJson的类型,可根据你实际的字段调整
interface GameItem {
  type: string;
  color: string;
  // 其他你需要的字段
}

const NewBet: React.FC = () => {
  // 这里替换为你实际的gamesJson数据源
  const gamesJson: GameItem[] = [];

  // 你原来的点击事件逻辑写在这里
  const whichGameIs = (index: number) => {
    console.log('当前选中的游戏索引:', index)
  };

  return (
    <LotoContainer id="bets-container-lotos">
      {/* 直接遍历数据源渲染所有Loto组件 */}
      {gamesJson.map((game, index) => (
        <Loto
          key={index}
          id={`bets-color-${index}`}
          value={`games${index}`}
          onClick={() => whichGameIs(index)}
          {/* 动态样式直接通过props传递,不需要后续查DOM修改 */}
          style={{
            color: game.color,
            borderColor: game.color
          }}
        >
          {game.type}
        </Loto>
      ))}
    </LotoContainer>
  );
};

如果你确实需要保留原生操作DOM的写法(非常不推荐,仅作兼容参考),需要确保组件挂载完成后再调用callGames:

const NewBet: React.FC = () => {
  useEffect(() => {
    // 组件挂载完成后执行,此时才能拿到DOM节点
    callGames();
  }, []);

  return <LotoContainer id="bets-container-lotos"></LotoContainer>;
};

注意这种写法只能插入原生HTML标签,不能插入React组件标签,无法渲染Loto组件,仅作特殊场景下的参考。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 14:18:02