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
相关产品推荐
相关产品推荐

