-
Notifications
You must be signed in to change notification settings - Fork 813
Open
Description
I have multiple views and on different views I have different maps, however, I need to display user location on every map, I decided to turn it into reusable component that would watch user location and update it when necessery as well as only return the Marker.
An example of a map code
import React from 'react';
import {Map, InfoWindow, Marker, GoogleApiWrapper} from 'google-maps-react';
import apiKey from './maps-api-key.js';
import UserLocation from '../shared-components/user-location.jsx';
const styles = {
map: {
maxWidth: '85%',
margin: '5% auto 0'
},
container: {
minHeight: '400px',
maxHeight: '800px',
height: '70%'
}
};
export class SingleMarkerMap extends React.Component {
constructor(props) {
super(props);
this.state = {
showingInfoWindow: false,
activeMarker: {},
selectedPlace: {}
};
}
onMarkerClick(props, marker) {
this.setState({
selectedPlace: props,
activeMarker: marker,
showingInfoWindow: true
});
}
onMapClicked() {
if (this.state.showingInfoWindow) {
this.setState({
showingInfoWindow: false,
activeMarker: null
});
}
}
render() {
const {google, coord, desc, title} = this.props;
const {onMapClicked, onMarkerClick} = this;
const {activeMarker, showingInfoWindow} = this.state;
return (
<Map
style={styles.map}
containerStyle={styles.container}
className="super-map-wrapper"
google={google}
initialCenter={coord}
onClick={onMapClicked.bind(this)}
zoom={13}>
<Marker
visible={true}
onClick={onMarkerClick.bind(this)}
title={desc}
name={title} />
<InfoWindow
marker={activeMarker}
visible={showingInfoWindow}>
<div style={{maxWidth:'40vw'}}>
<h2>{title}</h2>
<p>{desc}</p>
</div>
</InfoWindow>
<UserLocation/>
</Map>
);
}
}
export default GoogleApiWrapper(apiKey)(SingleMarkerMap);
and the contents of user-location.jsx
import React from 'react';
import {Marker} from 'google-maps-react';
const defaultLocation = {
lng: 2.1663020364940166,
lat: 41.382491852864234
};
export class UserLocation extends React.Component {
constructor() {
super();
this.state = {
coord: {},
visible: false
};
}
updateLocation(pos) {
let blueDot = {
url: '/img/map/bluedot.png',
};
if ('google' in window) {
blueDot.size = new google.maps.Size(32, 32);
blueDot.origin = new google.maps.Point(0, 0);
blueDot.anchor = new google.maps.Point(8, 8);
blueDot.scaledSize = new google.maps.Size(16, 16);
}
this.setState({
coord: {
lat: pos.coords.latitude,
lng: pos.coords.longitude
},
visible: true,
icon: blueDot
});
}
onErrorGettingLocation(err) {
console.log('error getting location', err);
}
componentWillMount() {
let gl = navigator.geolocation;
const glOptions = {
enableHighAccuracy: true,
timeout: 15000,
maximumAge: 0
};
gl.watchPosition(
this.updateLocation.bind(this),
this.onErrorGettingLocation.bind(this),
glOptions
);
}
render() {
let {visible, coord, icon} = this.state;
return visible ?
<Marker
position={defaultLocation}
icon={icon}
title="Your location"
name="marker name" /> :
null;
}
}
export default UserLocation;
With logging I can see that the user location component is mounted and updates, however the icon does not appear on the map.
If I write the userLocation as a simple Marker
directly inside the Map
I am able to see the dot. Code example below
import React from 'react';
import {Map, InfoWindow, Marker, GoogleApiWrapper} from 'google-maps-react';
import apiKey from './maps-api-key.js';
const styles = {
map: {
maxWidth: '85%',
margin: '5% auto 0'
},
container: {
minHeight: '400px',
maxHeight: '800px',
height: '70%'
}
};
export class SingleMarkerMap extends React.Component {
constructor(props) {
super(props);
this.state = {
showingInfoWindow: false,
activeMarker: {},
selectedPlace: {},
visible: false,
userLocationCoord: {}
};
}
onMarkerClick(props, marker) {
this.setState({
selectedPlace: props,
activeMarker: marker,
showingInfoWindow: true
});
}
onMapClicked() {
if (this.state.showingInfoWindow) {
this.setState({
showingInfoWindow: false,
activeMarker: null
});
}
}
// start from user location
updateLocation(pos) {
let blueDot = {
url: '/img/map/bluedot.png',
};
if ('google' in window) {
blueDot.size = new google.maps.Size(32, 32);
blueDot.origin = new google.maps.Point(0, 0);
blueDot.anchor = new google.maps.Point(8, 8);
blueDot.scaledSize = new google.maps.Size(16, 16);
}
this.setState({
userLocationCoord: {
lat: pos.coords.latitude,
lng: pos.coords.longitude
},
visible: true,
icon: blueDot
});
}
onErrorGettingLocation(err) {
console.log('error getting location', err);
}
componentWillMount() {
let gl = navigator.geolocation;
const glOptions = {
enableHighAccuracy: true,
timeout: 15000,
maximumAge: 0
};
gl.watchPosition(
this.updateLocation.bind(this),
this.onErrorGettingLocation.bind(this),
glOptions
);
}
// end from user location
render() {
const {google, coord, desc, title} = this.props;
const {onMapClicked, onMarkerClick} = this;
const {
activeMarker,
showingInfoWindow,
visible,
userLocationCoord,
icon
} = this.state;
return (
<Map
style={styles.map}
containerStyle={styles.container}
className="super-map-wrapper"
google={google}
initialCenter={coord}
onClick={onMapClicked.bind(this)}
zoom={13}>
<Marker
visible={true}
onClick={onMarkerClick.bind(this)}
title={desc}
name={title} />
<InfoWindow
marker={activeMarker}
visible={showingInfoWindow}>
<div style={{maxWidth:'40vw'}}>
<h2>{title}</h2>
<p>{desc}</p>
</div>
</InfoWindow>
{
visible ?
<Marker
position={userLocationCoord}
icon={icon}
title="marker title"
name="marker name" /> :
null
}
</Map>
);
}
}
export default GoogleApiWrapper(apiKey)(SingleMarkerMap);
Is there something I am missing here or the Marker
component cannot be inside standard react components?
Thank you
JipBoesenkool, RobertPTC, Jeffchiucp, fullmoon6661, liambai and 1 more
Metadata
Metadata
Assignees
Labels
No labels