React中使用renderToString为Google Maps InfoWindow填充内容时首次点击Polygon触发TypeError报错排查
解决React组件嵌入Google Maps InfoWindow时的
getCurrentStack错误 我之前也碰到过一模一样的问题,这个错误的根源其实是你用错了React的渲染API,而且整体实现思路有可以优化的地方,咱们一步步拆解:
错误触发的直接原因
你当前使用的是react-dom-server.browser.development.js这个包——它是React为浏览器环境打包的精简版本,并不包含服务端渲染所需的完整工具链,而getCurrentStack正是服务端渲染调试栈需要的函数,浏览器版里根本没实现这个方法,所以调用renderToString时就会报错。
而且更关键的是:在客户端场景下,完全没必要用renderToString来处理React组件,Google Maps的InfoWindow支持直接挂载真实DOM元素,绕字符串转换这一步反而会出问题。
你的实现还存在的逻辑问题
你在domready事件里才去生成和设置内容,但domready是InfoWindow已经渲染到DOM之后的回调,这时候再调用setContent会触发InfoWindow的二次渲染,打乱React的渲染上下文,进一步加剧错误。
正确的实现方案
直接跳过字符串转换,把React组件直接挂载到InfoWindow的DOM容器里,步骤如下:
1. 保持你的InfoWindow组件定义不变
interface InfoWindowProps { className: string; onClickButtonLabel: string; onClickAction: ListActionValue; mxObject: ObjectItem; } const InfoWindowContent = (props: InfoWindowProps) => { return ( <button className={props.className} onClick={() => props.onClickAction()}> <span className="glyphicon glyphicon-share-alt"></span> <span style={{ marginLeft: "4px" }}>{props.onClickButtonLabel}</span> </button> ); };
2. 重构Polygon点击事件的处理逻辑
直接创建DOM容器,挂载React组件后传给InfoWindow:
// 处理Polygon点击的函数 const handlePolygonClick = (event) => { // 1. 创建一个空div作为React组件的挂载容器 const infoWindowContainer = document.createElement('div'); // 先把静态内容(比如你的infoWindowName)插入容器 infoWindowContainer.innerHTML = `${infoWindowName}<br><br>`; // 2. 初始化InfoWindow,直接把容器作为内容 const infowindow = new google.maps.InfoWindow({ content: infoWindowContainer, position: event.latLng, // 用点击位置定位InfoWindow }); // 3. 打开InfoWindow后,挂载React组件到容器 infowindow.open(map); // map是你的Google Maps实例对象 // React 17及以下用ReactDOM.render ReactDOM.render( <InfoWindowContent className="your-custom-class" onClickButtonLabel="跳转详情" onClickAction={yourActionHandler} mxObject={yourMxObject} />, infoWindowContainer ); // React 18+建议用createRoot // import { createRoot } from 'react-dom/client'; // const root = createRoot(infoWindowContainer); // root.render(<InfoWindowContent {...yourProps} />); // 4. 关键:InfoWindow关闭时清理React组件,避免内存泄漏 google.maps.event.addListener(infowindow, 'closeclick', () => { // React 17及以下 ReactDOM.unmountComponentAtNode(infoWindowContainer); // React 18+ // root.unmount(); }); }; // 给你的Polygon绑定点击事件 maps.event.addListener(yourPolygonInstance, 'click', handlePolygonClick);
为什么这个方案能解决问题?
- 避开了
react-dom-server的浏览器版本限制,用客户端原生的React挂载API(ReactDOM.render/createRoot)来处理组件渲染,上下文完整不会报错; - 直接操作DOM容器,不需要字符串转换,避免了HTML转义、组件状态丢失等潜在问题;
- 添加了
closeclick事件的清理逻辑,防止组件残留导致内存泄漏。
内容的提问来源于stack exchange,提问作者Ivo Sturm
相关产品推荐
相关产品推荐

