google-map-react
NPM 包来创建 Google 地图和几个标记。
问题: 如何将默认的 Google 地图标记添加到地图上?
从这个 Github 问题来看,我们似乎需要使用 onGoogleApiLoaded 函数来访问内部 Google Maps API。
参考Google Maps JS API 文档中的示例,我们可以使用以下代码来渲染标记,但是我们如何定义对
map
的引用?
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: 'Hello World!'
});
当前代码:
renderMarkers() {
...
}
render() {
return (
<div style={{'width':800,'height':800}}>
<GoogleMap
bootstrapURLKeys={{key: settings.googleMapApiKey}}
defaultZoom={13}
defaultCenter={{
lat: this.props.user.profile.location.coordinates[1],
lng: this.props.user.profile.location.coordinates[0]
}}
onGoogleApiLoaded={({map, maps}) => this.renderMarkers()}
yesIWantToUseGoogleMapApiInternals
>
</GoogleMap>
</div>
);
}
编辑:
由于此答案已发布,
GoogleMapReact
元素的文档(可能还有 API)已更改以支持儿童。任何具有 lat
和 lng
的子项都将呈现在地图上的相应位置,正如@Jobsamuel 的答案所示。
onGoogleApiLoaded
回调不应用于此目的,因为它不如声明式样式,并且如果对地图进行更改,则不会重新运行。
原始答案(已过时):
从自述文件中的描述来看,这一点可能并不完全清楚,但
maps
参数实际上是地图 API 对象(map
当然是当前的 Google 地图实例)。因此,您应该将两者都传递给您的方法:
onGoogleApiLoaded={({map, maps}) => this.renderMarkers(map, maps)}
并使用它们:
renderMarkers(map, maps) {
let marker = new maps.Marker({
position: myLatLng,
map,
title: 'Hello World!'
});
}
在地图上添加标记并不像我们希望的那么容易,主要是因为令人困惑的文档,但这里有一个超级简单的示例:
const Map = props => {
return (
<GoogleMapReact
bootstrapURLKeys={{ props.key }}
defaultCenter={{lat: props.lat, lng: props.lng}}
defaultZoom={props.zoom}>
{/* This is the missing part in docs:
*
* Basically, you only need to add a Child Component that
* takes 'lat' and 'lng' Props. And that Component should
* returns a text, image, super-awesome-pin (aka, your marker).
*
*/}
<Marker lat={props.lat} lng={props.lng}} />
</GoogleMapReact>
)
}
const Marker = props => {
return <div className="SuperAwesomePin"></div>
}
查看文档,它提到“您可以使用 onGoogleApiLoaded 访问 Google Maps 地图和地图对象,在这种情况下,您需要将 yesIWantToUseGoogleMapApiInternals 设置为 true”,这帮助我完成了下面的代码。
import React from 'react';
import GoogleMapReact from 'google-map-react';
const GoogleMaps = ({ latitude, longitude }) => {
const renderMarkers = (map, maps) => {
let marker = new maps.Marker({
position: { lat: latitude, lng: longitude },
map,
title: 'Hello World!'
});
return marker;
};
return (
<div style={{ height: '50vh', width: '100%' }}>
<GoogleMapReact
bootstrapURLKeys={{ key: 'YOUR KEY' }}
defaultCenter={{ lat: latitude, lng: longitude }}
defaultZoom={16}
yesIWantToUseGoogleMapApiInternals
onGoogleApiLoaded={({ map, maps }) => renderMarkers(map, maps)}
>
</GoogleMapReact>
</div>
);
};
export default GoogleMaps;
基于MasterAM的回答。
如果你使用 React hooks,这个可以解决问题:
import React, { useMemo, useEffect } from 'react';
const createControlledPromise = () => {
let resolver;
let rejector;
const promise = new Promise((resolve, reject) => {
resolver = resolve;
rejector = reject;
});
return { promise, resolver, rejector };
};
const useMarker = ({ lat, lng }) => {
const {
promise: apiPromise,
resolver: handleGoogleApiLoaded
} = useMemo(
createControlledPromise,
[]
).current;
useEffect(
() => {
let marker;
apiPromise.then(api => {
const { map, maps } = api;
marker = new maps.Marker({ position: { lat, lng }, map });
});
return () => {
if (marker) {
marker.setMap(null);
}
};
},
[lat, lon],
);
return { handleGoogleApiLoaded };
};
const Location = ({
location: { locationName, lat, lng }
}) => {
const { handleGoogleApiLoaded } = useMarker({ lat, lng });
return (
<section>
<h1>{locationName}</h1>
<p>
<GoogleMapReact
bootstrapURLKeys={{ key: __GOOGLE_MAP_API_KEY__ }}
center={{ lat, lng }}
defaultZoom={11}
onGoogleApiLoaded={handleGoogleApiLoaded}
/>
</p>
</section>
);
};