Reputation: 2975
I'm using the react-google-maps
package for react, and for some reason when it renders it's just grey. If the responsive state changes then it does appear weirdly.
I've wrapped the package in a custom component for re-usablility, and the code is:
import _ from 'lodash';
import exact from 'prop-types-exact';
import propTypes from 'prop-types';
import withScriptjs from 'react-google-maps/lib/async/withScriptjs';
import { GoogleMap as GMap, withGoogleMap } from 'react-google-maps';
import React, { Component } from 'react';
const apiKey = 'api_key';
const AsyncMap = _.flowRight(
withScriptjs,
withGoogleMap,
)(props => (
<GMap
defaultCenter={props.defaultCenter}
defaultZoom={props.defaultZoom}
onClick={props.onClick}
ref={props.onMapLoad}
>
{props.children}
</GMap>
));
class GoogleMap extends Component {
render() {
return (
<AsyncMap
googleMapURL={`https://maps.googleapis.com/maps/api/js?v=3.exp&key=${apiKey}`}
loadingElement={<div>{'loading...'}</div>}
{...this.props}
/>
);
}
}
GoogleMap.propTypes = exact({
containerElement: propTypes.object,
defaultCenter: propTypes.object.isRequired,
defaultZoom: propTypes.number,
mapElement: propTypes.object,
onClick: propTypes.func,
});
GoogleMap.defaultProps = {
containerElement: (<div style={{ height: '250px' }} />),
mapElement: (<div style={{ height: '250px' }} />),
defaultZoom: 5,
onClick: _.noop,
};
export default GoogleMap;
And it's called like so:
<GoogleMap
containerElement={<div className={'overnight-storage-map'} style={{ height: '250px' }} />}
defaultCenter={storageLocation}
defaultZoom={3}
>
<Marker
defaultAnimation={2}
key={`marker-${s.id}`}
position={storageLocation}
/>
</GoogleMap>
Upvotes: 1
Views: 2571
Reputation: 121
New Answer - June 2023
I ran into a similar issue and found this thread in my research. I am using the @react-google-maps/api
NPM package with Next.js, and the following code produced a grey map. However, I know that the map component itself was rendering, because when scrolling across the map, I still got the "Use ⌘ + scroll to zoom the map" message that you would normally get with Google Maps.
<GoogleMap
onLoad={onLoad}
onUnmount={onUnmount}
mapContainerClassName='w-full h-full'
mapTypeId='satellite'
zoom={9}
>
</GoogleMap>
The solution was thankfully quite simple, but I only managed to find it by trial and error - Make sure to set the "center" property on the Map component:
<GoogleMap
onLoad={onLoad}
onUnmount={onUnmount}
mapContainerClassName='w-full h-full'
mapTypeId='satellite'
zoom={9}
center={{ lat: 33.8588611, lng: -84.2484869 }}
>
</GoogleMap>
And just like magic, it started loading correctly!
I hope that this answer helps somebody else down the road with the same issue as me, but where none of the other Stackoverflow answers or GitHub issues that talk about resizing seem to fix the issue.
Cheers!
Upvotes: 3
Reputation: 2975
The problem ended up being that this was rendered inside an accordion that wasn't expanded by default. I just wrote a function that called the native resize
method on the map when the accordion is expanded/collapsed.
import _ from 'lodash';
import exact from 'prop-types-exact';
import propTypes from 'prop-types';
import withScriptjs from 'react-google-maps/lib/async/withScriptjs';
import { GoogleMap as GMap, withGoogleMap } from 'react-google-maps';
import React, { Component } from 'react';
const apiKey = 'api_key';
const AsyncMap = _.flowRight(
withScriptjs,
withGoogleMap,
)(props => (
<GMap
defaultCenter={props.defaultCenter}
defaultZoom={props.defaultZoom}
onClick={props.onClick}
ref={props.onMapLoad}
>
{props.children}
</GMap>
));
class GoogleMap extends Component {
constructor(props) {
super(props);
this.state = {
dragged: false,
};
this.dragged = this.dragged.bind(this);
this.onMapLoad = this.onMapLoad.bind(this);
this.resize = this.resize.bind(this);
}
dragged() {
this.setState({ dragged: true });
}
onMapLoad(map) {
if (!map) return;
this._map = map;
this._mapContext = this._map.context.__SECRET_MAP_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
this._mapContext.addListener('drag', this.dragged);
}
resize() {
window.google.maps.event.trigger(this._mapContext, 'resize');
if (!this.state.dragged)
this._mapContext.setCenter(this.props.defaultCenter);
}
render() {
return (
<AsyncMap
googleMapURL={`https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places&key=${apiKey}`}
loadingElement={<div>{'loading...'}</div>}
onMapLoad={this.onMapLoad}
{...this.props}
/>
);
}
}
GoogleMap.propTypes = exact({
children: propTypes.any,
containerElement: propTypes.object,
defaultCenter: propTypes.object.isRequired,
defaultZoom: propTypes.number,
mapElement: propTypes.object,
onClick: propTypes.func,
});
GoogleMap.defaultProps = {
containerElement: (<div style={{ height: '250px', width: '100%' }} />),
mapElement: (<div style={{ height: '250px', width: '100%' }} />),
defaultZoom: 5,
onClick: _.noop,
};
export default GoogleMap;
Upvotes: 1