Google Map React component loses data when placed into divs - reactjs

I have a working GoogleMapReact component that takes latitude and longitude, and places markers on the map. The problem I face is I need to style the Marker component and when I place it into DIV or any other html element, all markes lose their coordinates and are just in vertical row on the map.
Here is the code:
import React, { useState } from "react";
import GoogleMapReact from "google-map-react";
import getCenter from "geolib/es/getCenter";
import Marker from "../components/Marker";
function MapMe1({ searchResults }) {
//transform the search results object into {latitude,longitude} format
const coordinates = searchResults.map((result) => ({
longitude: result.long,
latitude: result.lat,
}));
const center = getCenter(coordinates);
const [viewport, setViewport] = useState({
width: "600px",
height: "max-height: 75%",
center: { lat: center.latitude, lng: center.longitude },
zoom: 11,
});
return (
<GoogleMapReact
//mapContainerStyle={containerStyle}
bootstrapURLKeys={{ key: process.env.google_maps_key }}
{...viewport}
onViewportChange={(nextViewport) => setViewport(nextViewport)}
>
{searchResults.map((result) => (
// It works, but if I wrap this in <div> lat and lng no longer available...
<Marker
lat={result.lat}
lng={result.long}
offsetLeft={-20}
offsetTop={-10}
titles={result.title}
/>
))}
</GoogleMapReact>
);
}
export default MapMe1;
I want to style the marker to show a tooltip but for some reason is the Marker component loses all data. Why is this happening?

Related

ReacMapboxGl Marker doesn't show on map

import ReactMapboxGl, { Marker } from "react-mapbox-gl";
import React from "react";
const Map = ReactMapboxGl({
accessToken: process.env.REACT_APP_MAPBOX_TOKEN,
});
export default function App() {
return (
<Map
style="mapbox://styles/mapbox/streets-v9"
containerStyle={{
height: "100vh",
width: "100vw",
}}
center={[-74.006, 40.7128]}
>
<Marker coordinates={[-74.006, 40.7128]}>
<div>IAM HEEEEEEEEEEEEEEEEERE</div>
</Marker>
</Map>
);
}
This is a basic map showing using mapbox-react-gl.
There is no bug showing in console log but I can not see the marker on the map.
I think you didn't set the coordinates correctly (latitude, longitude)
They should be, based in your example [40.7128 -74.006]

#react-google-maps Marker LatLng throwing error

I'm using the #react-google-maps/api to build my first react map.. But my latLng literal for position inside the Marker is breaking my code. Is this not the same latLng format that I'm using for center which works fine? How is my Marker latLng wrong? That seems to be the only required attribute in the docs so I'm at a dead end.
import React, { Component } from 'react';
import { GoogleMap, LoadScript, Marker } from '#react-google-maps/api';
import icon1 from '../map/icon1.svg';
import iconDead from '../map/iconDead.svg';
const center = { lat: 51.510228, lng: -0.132992 };
const API = 'xxxx';
const containerStyle = {
width: '100%',
height: '800px'
};
function MyComponent( markers, onToggleOpen ) {
return (
<LoadScript
googleMapsApiKey={API}
>
<GoogleMap
mapContainerStyle={containerStyle}
center={center}
zoom={10}
>
<Marker position={ lat: 51.510228, lng: -0.132992 }></Marker>
<></>
</GoogleMap>
</LoadScript>
)
}
export default React.memo(MyComponent)
The position property is an object. Hand your lat and lng values like this:
<Marker position={{lat: 51.510228, lng: -0.132992}}></Marker>

ReactJS useState, onClick show InfoWindow

In my react google maps code I am not able to set onclick open InfoWindow. I am referring to this tutorial: https://youtu.be/WZcxJGmLbSo?t=1545
my code:
import React, { useState } from "react";
import {
GoogleMap,
useLoadScript,
Marker,
InfoWindow,
} from "#react-google-maps/api"; // --> using #react package
const libraries = ["places"];
const mapContainerStyle = {
width: "100%",
height: "100vh",
};
const center = {
lat: 51.103807,
lng: 10.057477,
};
export default function App() {
const [setSState, sstate] = React.useState(null);
const { isLoaded, loadError } = useLoadScript({
googleMapsApiKey: process.env.REACT_APP_GOOGLE_KEY,
libraries,
});
if (loadError) return "error loading maps";
if (!isLoaded) return "loading maps";
return (
<div>
<GoogleMap
mapContainerStyle={mapContainerStyle}
zoom={6}
center={{ lat: 50.115509, lng: 8.690508 }}
>
<Marker
position={{ lat: 51.081753, lng: 13.696073 }}
onClick={() => {
sstate(!setSState);
console.log("marker clicked");
}}
}}
></Marker>
</GoogleMap>
</div>
);
}
I am not able to show the marker only when clicked. What shall I do? I am hard coding the data for now. I am still new to props.
And when click the X on marker and click on the marker again it crashes. I know I have to use onCloseClick which when I tried didnt work.
Have a look at the useState Hook docs.
The hook will give you a state variable to use, and a function that can be used to update that variable.
At the top of the component you want to have:
const [centerState, setCenterState] = useState(null);
and then you can use this in the Marker to update the state:
onClick={() => setCenterState(center)}
That will update the state, but in your code you are currently getting center from an object assigned outside of the component, you might want to think about what you are going to set in that state.

Is this the correct usage of React Components?

I am new to React. I want to share my components files with you. The code is syntactically correct and executes just fine. I just want to know, if its logically correct and the correct use of concepts such as states.
Is it correct to save lng and lat coords from the GeoLocation API to the MapContainer State?
Is it the correct use of ComponentDidMount() function.
What other ways can I improve the code.
// Map.js
import React from 'react'
import 'bootstrap/dist/css/bootstrap.css';
import GoogleMapReact from 'google-map-react';
function Map(props) {
const screenHeight = window.screen.height;
return (
<div style={{ height: screenHeight - 250 }}>
<GoogleMapReact
bootstrapURLKeys={{ key: "123mykey" }}
center={props.center}
defaultZoom={props.zoom}
></GoogleMapReact>
</div>
);
}
Map.defaultProps = {
center: {
lat: 59.95,
lng: 30.33
},
zoom: 11
};
export default Map
// MapContainer.js
import React from 'react'
import 'bootstrap/dist/css/bootstrap.css';
import Map from './Map'
class MapContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
center: {
lat: 0, lng: 0
}
}
this.getLocation = this.getLocation.bind(this);
this.showPosition = this.showPosition.bind(this);
}
getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(this.showPosition);
} else {
console.log("Geolocation is not supported by this browser.");
}
}
showPosition(position) {
this.setState({
center: {
lat: position.coords.latitude,
lng: position.coords.longitude
}
});
}
componentDidMount() {
this.getLocation();
}
render() {
return (
<div className="row">
<div className="col-md-9">
<Map center={this.state.center} />
</div>
<div className="col-md-3 d-sm-none d-md-block d-none d-sm-block">
<h1>Menu</h1>
</div>
</div>
);
}
}
export default MapContainer
Looks fine to me. You only need to import 'bootstrap/dist/css/bootstrap.css'; in your main index.js file.
Everything seems good, you are doing right
Is it correct to save lng and lat coords from the GeoLocation API to the MapContainer State?
Is it the correct use of ComponentDidMount() function?
Yeah, Why not ?
What other ways can I improve the code.
there are some minor changes like:
1- you can import Component on top and the class definition would be smaller
2- it is a good practice to use arrow function component definition like this
export default (props) => {
const screenHeight = window.screen.height;
return (
<div style={{ height: screenHeight - 250 }}>
<GoogleMapReact
bootstrapURLKeys={{ key: "AIzaSyCV1fQD2VC6HoNbuuSPkE0q_QZvDf117PY" }}
center={props.center}
defaultZoom={props.zoom}
></GoogleMapReact>
</div>
);
}
generally you are using react in right way, keep going
It looks fine at MapContainer (Example 2) but I propose separate your view based logics and the others. For example, the getLocation function is not based on your view (not depending React component or changing the view) so we can plug out this logic function into an independent function later the showPosition function is going to use that function.

Forwarding refs with memoised map: undefined is not a function (near mapRef.animateToRegion)

I have the following React Native component, utilising react-natve-maps for map displays. I require a ref to the map to use its animateToRegion function in a separate component, and as I am using React's memo to prevent unnecessary re-renders during expensive map draws (eg, heatmaps), I am therefore also using forwardRef as functional components cannot have ref props.
I've ended up with the following:
import React from 'react';
import {
StyleSheet,
View,
} from 'react-native';
import {
MapView,
Marker,
} from 'react-native-maps';
const MemoMap = React.memo(
React.forwardRef((props, ref) =>(
<MapView
ref={ref}
initialRegion={{
latitude: 0,
longitude: 5,
latitudeDelta: 0.01,
longitudeDelta: 0.01,
}}
style={StyleSheet.absoluteFillObject}>
<Marker
coordinate={{
latitude: 0,
longitude: 5,
}} />
</MapView>
)
), () => false);
export default function App() {
const mapRef = React.createRef();
const snapToMarker = () => {
mapRef.animateToRegion({
longitude: 0,
latitude: 0,
longitudeDelta: 0.01,
latitudeDelta: 0.01,
})
};
return (
<View>
<MemoMap ref={mapRef} />
<Button onPress={snapToMarker} />
</View>
);
}
(I've mocked the memo equality function for simplicity)
However, the ref always has current: null and not the map reference. Therefore, clicking the button simply throws undefined on the animateToRegion event call.
What can I do to get the map reference I require?

Resources