Electron+React+TS环境下renderer.js获取React元素为null该如何解决?
问题描述
我正在使用Electron、preload、renderer结合React和TypeScript进行开发,遇到DOM元素获取问题,相关代码如下:
index.html
<body> <div id="root" /> <script src='./renderer.js'/></body>
index.ts
const root = ReactDOM.createRoot( document.getElementById("root") as HTMLElement ); root.render(<App />);
App.ts
<div className="App"> <header></header> <MainPage /> </div>
MainPage.ts
<div> <btn id='load' /> </div>
renderer.js
console.log(document) ----------------------------> OK console.log(document.getElementById('root')) ------> OK console.log(document.getElementById('load')) ------> null
请问如何在renderer.js中使用id为'load'的按钮?我遗漏了什么?
解决方案
1. 核心问题:渲染时机不匹配
renderer.js在页面加载后立即执行,但React组件的渲染是异步过程,此时load按钮还未被挂载到DOM树,所以获取结果为null。
2. 额外问题:错误的HTML标签
React中不存在<btn>原生标签,你应该使用标准的<button>标签,否则React会将其视为自定义组件,不会渲染成可识别的DOM按钮元素。
可行解决方法
方法一:React组件内处理(推荐)
React项目中,优先通过React自身的API处理元素交互,避免直接操作DOM。修改MainPage.ts:
import { useRef, useEffect } from 'react'; const MainPage = () => { const loadBtnRef = useRef<HTMLButtonElement>(null); useEffect(() => { if (loadBtnRef.current) { loadBtnRef.current.addEventListener('click', () => { // 这里编写按钮逻辑 console.log('按钮触发'); }); } }, []); return ( <div> <button ref={loadBtnRef} id='load'>加载</button> </div> ); }; export default MainPage;
方法二:等待React渲染完成后获取(不推荐)
如果必须在renderer.js中操作,需要监听React渲染完成的信号,比如用MutationObserver监听根节点变化:
document.addEventListener('DOMContentLoaded', () => { const root = document.getElementById('root'); const observer = new MutationObserver(() => { const loadBtn = document.getElementById('load'); if (loadBtn) { // 找到按钮后执行逻辑 console.log('已获取按钮:', loadBtn); observer.disconnect(); // 停止监听 } }); observer.observe(root, { childList: true, subtree: true }); });
内容的提问来源于stack exchange,提问作者so_
相关产品推荐
相关产品推荐

