【问题标题】:React Render HTML to Infowindow using @React-Google-Maps/api使用 @React-Google-Maps/api 将 HTML 渲染到 Infowindow
【发布时间】:2020-09-05 17:40:33
【问题描述】:

如何在谷歌地图信息窗口中呈现 html?

我尝试了几种不同的方法来做到这一点,但它们似乎都不起作用。

我的代码:

import React, { Component, useState } from 'react';
import ReactDOMServer from 'react-dom/server';
import { GoogleMap, LoadScript, useLoadScript, InfoWindow, Marker, } from '@react-google-maps/api'

export class MarkerWithInfoWindow extends React.Component {

    constructor() {
        super();
        this.state = {
            isOpen: false
        }
        this.onToggleOpen = this.onToggleOpen.bind(this);
        this.onEventWindowClick = this.onEventWindowClick.bind(this)
    }

    onToggleOpen() {
        this.setState({
            isOpen: !this.state.isOpen
        });
    }



    render() {

        const imgUrl = this.props.icon;
        return (<Marker
            title={this.props.title}
            position={this.props.position}

            icon={{
                url: imgUrl,
            }}
        >
            {this.state.isOpen && <InfoWindow
                onCloseClick={this.onToggleOpen}
                position={this.props.position}
                onMouseOut={this.onToggleOpen}
                pixelOffset={{ width: 25, height: 25 }}
                zIndex={-1}
                onClick={this.onEventWindowClick(this)} 
            >
                <> {ReactDOMServer.renderToString(this.props.content)}</>
            </InfoWindow>}
        </Marker>)
    }
}

我的结果如下所示:

【问题讨论】:

    标签: html reactjs google-maps infowindow


    【解决方案1】:

    我猜content prop 是作为 HTML 字符串传递的,那么需要将 dangerouslySetInnerHTML 设置为将其呈现为 html 而不是将其作为纯字符串返回,例如:

    const InfoWindowContent = () => <div dangerouslySetInnerHTML={{ __html: this.props.content }}></div>;
    

    用法

    <InfoWindow
         onCloseClick={this.onToggleOpen}
         position={this.props.position}>
          <InfoWindowContent/>
    </InfoWindow>
    

    Demo

    【讨论】:

      【解决方案2】:

      我只是将其作为一个功能组件。根据 Google Map API 文档,所需的 HTML 内容可以作为 InfoWindow 实例在其实例化时的 content 属性的值传递。根据react-google-maps/api 的文档,(初始)选项可以作为InfoWindow JSX 中的道具传递。

      在我的例子中,我动态地重新计算 InfoWindow 内容,所以我将该字符串作为一个状态(在我的例子中为dataWindowContent)。 React 保证每次状态更改时都会重新渲染 InfoWindow 组件,这就是我保持最新状态的方式。

      最后,在 InfoWindow 组件默认打开的情况下创建 InfoWindow 组件。我一直关闭,直到它有东西要显示,所以我把这个行为放在 onInfoWindowLoad 处理程序中。

      您需要一个对底层 Google Maps API 实例的引用——InfoWindow 组件在调用 onLoad 处理程序时方便地将该对象作为参数传递。所以这里是你如何做你正在尝试的事情的草图(请注意,我没有练习过这个,我只是想说你可能会尝试什么):

      const MarkerWithInfoWindow = ( {content, title, position, icon, ...props} ) => {
        const [infoWindowContent, setInfoWindowContent] = useState(content);
        const [localPosition, setLocalPosition] = useState(position);
        const rawInfoWindowRef = useRef(null);
      
        const onInfoWindowLoad = (aRawInfoWindow) => {
          rawInfoWindowRef.current = aRawInfoWindow;
          if (''===infoWindowContent) {
            aRawInfoWindow.close();
          }
        };
        return (
          <GoogleMap>
            <Marker
              title={title}
              position={localPosition}
              icon={{url: icon}}
            >
            <InfoWindow
              onLoad={onInfoWindowLoad}
              onCloseClick={onInfoWindowClick}
              options={{content: infoWindowContent}}
              position={localPosition}         
            />
            </Marker>
          <GoogleMap>
        );
      };
      

      请注意,我已将您所需的 HTML 作为其 option 属性内的 content 参数的值传递给 InfoWindow 实例。

      还要注意positioncontent 属性用于初始化相应的本地状态。使用他们的设置器移动标记/信息窗口或移动地图。另请注意,我已经用包含 GoogleMap 包围了您的标记和信息窗口。我很确定组件需要这个容器。您可能需要将包含地图的 center 属性设置为另一个状态,以便在位置更改时更改。

      这种方法可以让您避免使用dangerouslySetInnerHTML。更改 infoWindowContent 的唯一方法是使用其设置器 (setInfoWindowContent),这将强制重新渲染组件树。在重新渲染中,低级 InfoWindow 实例将自动更新其新内容,并渲染 HTML。

      【讨论】:

        猜你喜欢
        • 2013-01-18
        • 2022-08-22
        • 2014-06-08
        • 1970-01-01
        • 1970-01-01
        • 2020-09-19
        • 2021-10-20
        • 2019-05-14
        • 1970-01-01
        相关资源
        最近更新 更多