Please help. I am trying to load a map using my API KEY.
The problem is that neither map nor props are loading. Probably I'm missing the point.
Any ideas?
Here's the repo
And here's the Map Container's code
import React, { Component } from 'react';
import {GoogleApiWrapper, Map} from 'google-maps-react';
const API_KEY = 'apikeystring';
export class Container extends Component {
render() {
const style = {
width: '200px',
height: '200px'
}
if (!this.props.loaded) {
return <div>Loading props...</div>
}
return (
<div style={style}>
<Map
google={window.google}
initialCenter={{
lat: 44.498955,
lng: 11.327591
}}
style={{
width: '100px',
height: '100px'
}}
/>
</div>
)
}
}
export default GoogleApiWrapper({
apiKey: (API_KEY)
})(Container)
What am I doing wrong?
In order to show your Loading props, you have to do it like this:
return (
<div style={style}>
{(!this.props.loaded) ? <div>Loading props...</div> : null}
<Map
google={window.google}
initialCenter={
lat: 44.498955,
lng: 11.327591
}
style={{
width: '100px',
height: '100px'
}}
/>
</div>
I’m not sure but I don’t think you need double courly braces for initialCenter, hope it helps.
Related
import React from 'react';
import Gallery from '../Gallery/Gallery';
const Galleries = (props) => {
const galleries = [
{
name: 'natur',
src: ' ../../Images/photographer-gfc1c015b1_1920.jpg',
},
{
name: 'moutain',
src: ' ../../Images/photographer-gfc1c015b1_1920.jpg',
},
];
return (
<div>
{/* generate the numbre of data */}
<h1>I have {galleries.length} Images</h1>
{galleries.map((gallery) => (
<Gallery name={gallery.name} galery={gallery.src} />
))}
</div>
);
};
export default Galleries;
import React from 'react';
const Gallery = (props) => {
return (
<div>
<h1>{props.name}</h1>
<img src={props.src} alt="" style={{ height: '200px', width: '300px' }} />
</div>
);
};
export default Gallery;
here is your mistake, wrong props are getting used,
you are passing this <Gallery name={gallery.name} galery={gallery.src} />
change this line, this is wrong line, using src, but you never passed src,
<img src={props.src} alt="" style={{ height: '200px', width: '300px' }} />
change to this, this will work fine, props.galery works
<img src={props.galery} alt="" style={{ height: '200px', width: '300px' }} />
I have this props but still get the same error. Required props loadingElement or googleMapURL is missing. You need to provide both of them.
import React from 'react';
import { GoogleMap,
withScriptjs,
withGoogleMap } from 'react-google-maps'
function Mapp () {
return (
<GoogleMap
defaultZoom = { 10 }
defaultCenter = {{ lat: 45.421532, lng: -75.697189 }}
/>
)
}
const WrapperMap = withScriptjs( withGoogleMap(Mapp))
export default function Maps() {
return (
<div style = {{ width: "100vw", height: "100vh" }}>
<WrapperMap
googleMapUrl = {`https://maps.googleapis.com/maps/api/js?
v=3.exp&libraries=geometry,
drawing,places&key=YOUR_KEY`}
loadingElement = { <div style={{ height: `100%` }} />}
containerElement = { <div style={{ height: `400px` }} />}
mapElement = { <div style={{ height: `100%` }} />}
/>
</div>
)
}
The issue with your code is that you are using the parameter googleMapUrl instead of googleMapURL. Once you change this, the code will successfully run. I also removed your API key. Please don't share your API key in public sites like StackOverflow in the future.
Here's a working code.
I have 2 sibling components in 1 parent component. It's like this:
import React, { useState } from 'react';
import PlaceSearchInput from './PlaceSearchInput';
import { GoogleMap, withGoogleMap } from "react-google-maps";
export default function Search(props) {
const [mapCenter, setMapCenter] = useState({lat:3, lng:2});
function Map() {
return (
<div>
<GoogleMap defaultZoom={10} center={mapCenter}/>
</div>
)
}
const WrappedMap = withGoogleMap(Map);
if (!props.isGoogleMapApiReady)
return (
<div>Loading...</div>
)
return (
<div style={{ margin: "100px" }}>
<div style={{ height: "50vh", width: "50vh" }}>
<WrappedMap
loadingElement={<div style={{ height: "100%" }} />}
containerElement={<div id="map" style={{ height: "100%" }} />}
mapElement={<div style={{ height: "100%" }} />}
/>
<PlaceSearchInput setMapCenter={setMapCenter} />
</div>
</div>
)
}
I want Input sets coordinates and Map shows the coordinates. I know one way is that having coordinates state in parent and then passing set function to Input, coordinates to Map. But with this way I found out it whenever state is changed by Input component, though Map does move to new coordinates, Map is refreshed and that is what I want to avoid. Is there way to solve it?
Try this, I moved Map and WrappedMap's creation out of the of the Search component.
I believe that the change in the component definition every time the component re-rendered likely caused react to think it's an entirely new component and unmount the old and mount the new rather than re-render.
import React, { useState } from 'react';
import PlaceSearchInput from './PlaceSearchInput';
import { GoogleMap, withGoogleMap } from 'react-google-maps';
function Map({ center }) {
return (
<div>
<GoogleMap defaultZoom={10} center={center} />
</div>
);
}
const WrappedMap = withGoogleMap(Map);
export default function Search(props) {
const [mapCenter, setMapCenter] = useState({ lat: 3, lng: 2 });
if (!props.isGoogleMapApiReady) {
return <div>Loading...</div>;
}
return (
<div style={{ margin: '100px' }}>
<div style={{ height: '50vh', width: '50vh' }}>
<WrappedMap
loadingElement={<div style={{ height: '100%' }} />}
containerElement={<div id="map" style={{ height: '100%' }} />}
mapElement={<div style={{ height: '100%' }} />}
center={mapCenter}
/>
<PlaceSearchInput setMapCenter={setMapCenter} />
</div>
</div>
);
}
hi all im trying to implement google maps in react.js , the map is showing fine however when i try to show my marker , nothing is being displayed. IF i remove lat and long values then marker will show up on top of the map. But if i add lat and long values to it , then it stops showing. Can someone please help?
import React, { Component } from 'react';
import GoogleMapReact from 'google-map-react';
import marker from './marker.png';
import { geolocated } from 'react-geolocated';
const AnyReactComponent = ({ text }) => (
<div>
<img src={marker} style={{ height: '50px', width: '50px' }} />
</div>
);
export default class Map extends Component {
static defaultProps = {
zoom: 11,
};
Componentwillmount() {
console.log(this.props.center.latitude);
}
render() {
return (
<div className="google-map" style={{ width: '100%', height: '2000px', backgroundColor: 'red' }}>
<GoogleMapReact
options={{
styles:ExampleMapStyles
}}
center={this.props.center} defaultZoom={this.props.zoom}>
<AnyReactComponent
lat={59.955413}
lng={30.337844}
text={'Kreyser Avrora'}
/>
</GoogleMapReact>
</div>
);
}
}
The documentation shows that you can use<AnyReactCompenent/> which you can use if you want to have your own Marker or text. However, if you wish to use the default marker then you would have to pass as a property into the <GoogleMapReact></GoogleMapReact> component. The docs mention 'You can access Google Maps map and maps objects by using onGoogleApiLoaded, in this case, you will need to set yesIWantToUseGoogleMapApiInternals to true'. This just means add the name of the property without passing a value to it as I have in mine. It may not be entirely clear from the description in the Readme, but the maps argument is, in fact, the maps API object (and map is, of course, the current Google Map instance). Therefore, you should pass both into the method with the renderMarkers = (map, maps) => {} function.
You can try this:
import React, { Fragment } 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 (
<Fragment>
<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>
</Fragment>
);
};
export default GoogleMaps;
I think the main question that you need to answer is: What are your center props?
I used your code in sandbox and did a some small adaption: I used the same lat/longitude where your marker should be rendered in order to see at a glance whether it is actually shown. And it is:
https://codesandbox.io/s/00p1ry2v0v
export default class Map extends Component {
static defaultProps = {
zoom: 11,
center: {
lat: 49.955413,
lng: 30.337844
}
};
render() {
const mapStyles = {
width: "100%",
height: "100%"
};
return (
<div
className="google-map"
style={{ width: "100%", height: "2000px", backgroundColor: "red" }}
>
<GoogleMapReact
style={mapStyles}
center={this.props.center}
defaultZoom={this.props.zoom}
>
<AnyReactComponent
lat={49.955413}
lng={30.337844}
text={"Kreyser Avrora"}
/>
</GoogleMapReact>
</div>
);
}
}
So, make sure you start the map with a proper initial center position. :)
I have an airbnb-like app with cards on the left and a google map on the right (using the react-google-maps package)
I would like to highlight (in the code below through an animation) a marker when the user hovers on its corresponding card.
I actually managed to do so (see code below) but the problem is, the map component rerenders when another card is hovered on by the user.
Is there a way to do so without having the map to rerender everytime ?
My App.js (simplyfied for comprehension purposes):
import React from "react";
import { Meals } from "../api/meals.js";
import { Restaurants } from "../api/restaurants.js";
import MealCard from "./MealCard";
import MealsMap from "./MealsMap";
class App extends React.Component {
constructor() {
super();
this.state = {
highlightedMarker: ""
};
this.renderMeals = this.renderMeals.bind(this);
this.highlightMarker = this.highlightMarker.bind(this);
}
renderMeals() {
return this.props.meals.map(m => (
<div
className="col-sm-6 col-xs-12 "
key={m._id}
onMouseOver={() => this.highlightMarker(m.restaurant)}
>
<MealCard
name={m.name}
restaurant={
this.props.restaurants.find(r => r._id === m.restaurant).name
}
image={m.image}
address={
this.props.restaurants.find(r => r._id === m.restaurant).address
}
/>
</div>
));
}
renderMap() {
return (
<MealsMap
restaurants={this.props.restaurants}
highlightedMarker={this.state.highlightedMarker}
/>
);
}
highlightMarker(restaurantId) {
this.setState({ highlightedMarker: restaurantId });
}
render() {
return (
<div>
<div className="app-wrapper" style={{ display: "flex" }}>
<div className="container">
<div className="row">{this.renderMeals()}</div>
</div>
{this.renderMap()}
</div>
</div>
);
}
}
and my MealsMap.js:
import React from "react";
import { withGoogleMap, GoogleMap, Marker } from "react-google-maps";
class MealsMap extends React.Component {
render() {
const GoogleMapMeals = withGoogleMap(props => (
<GoogleMap
defaultCenter={{ lat: 50.6320134, lng: 3.0568584 }}
defaultZoom={13}
>
{this.props.restaurants.map(r => (
<Marker
key={r._id}
position={{ lat: Number(r.lat), lng: Number(r.lng) }}
animation={
this.props.highlightedMarker === r._id
? google.maps.Animation.BOUNCE
: ""
}
/>
))}
</GoogleMap>
));
return (
<GoogleMapMeals
containerElement={
<div
style={{
flex: "0 0 400px",
height: "100vh",
position: "sticky",
top: "0"
}}
/>
}
mapElement={
<div
style={{
height: "100%",
width: "100%",
position: "absolute",
top: "0px",
left: "0px",
backgroundColor: "rgb(229, 227, 223)"
}}
/>
}
/>
);
}
}
export default MealsMap;
You don't want to define the GoogleMapMeals component inside of the render method of MealsMap, since that will result in a new component each render which will make React unmount the previous one and create an entirely new one.
You could define GoogleMapMeals outside of the render method instead.
Example
const GoogleMapMeals = withGoogleMap(props => (
<GoogleMap
defaultCenter={{ lat: 50.6320134, lng: 3.0568584 }}
defaultZoom={13}
>
{props.markers.map(r => (
<Marker
key={r._id}
position={{ lat: Number(r.lat), lng: Number(r.lng) }}
animation={
props.highlightedMarker === r._id
? google.maps.Animation.BOUNCE
: ""
}
/>
))}
</GoogleMap>
));
class MealsMap extends React.Component {
render() {
return (
<GoogleMapMeals
markers={this.props.restaurants}
highlightedMarker={this.props.highlightedMarker}
containerElement={
<div
style={{
flex: "0 0 400px",
height: "100vh",
position: "sticky",
top: "0"
}}
/>
}
mapElement={
<div
style={{
height: "100%",
width: "100%",
position: "absolute",
top: "0px",
left: "0px",
backgroundColor: "rgb(229, 227, 223)"
}}
/>
}
/>
);
}
}