Custom Marker as a component.
See original GitHub issueI 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
Issue Analytics
- State:
- Created 6 years ago
- Reactions:6
- Comments:6
Top Results From Across the Web
Custom Marker as a React Component with react-google ...
Instead of the default Google Maps markers, balloons and other map components, you can render your cool animated react components on the map....
Read more >Google Maps and React With a Custom Marker
Google Map React is a component wrapping a set of the Google Maps API ... Now we will create a custom marker instead...
Read more >Building A Custom Google Maps Marker ... - Daw-Chih Liou
We will be building a proof of concept to create customer Google Maps markers using any React component in a Next.js project.
Read more >CustomMarker | React InstantSearch - Algolia
This component is an alternative to <Marker /> . In some cases, you may want to have the full control of the marker...
Read more >Custom Markers | Maps JavaScript API - Google Developers
Adds the icon property to the MarkerOptions object, to change the marker's icon. The icon property can be either a string (the URL...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
The Marker component can’t be rendered inside another component since the map does not render its children in the traditional manner. You can get around this by returning the JSX directly to where you need it by calling the render function on a React component or by using a function as I did below.
This issue should remain open though since the original approach is the React way of doing it…
From this https://github.com/fullstackreact/google-maps-react/issues/51 I found that explicitly pass the props from the parent actually work In your case, it would be something like
and in the
user-location.jsx
should be likeI’m not sure if this is the right way of doing it