我正在使用本机google maps API开发一个google maps应用。我有一个主要组件(app.js),一个地图(map.js)和InfoWindowD(InfoWindowD.js)
我在InfoWindowD组件中的<select onChange>...</select>
在App(app.js)中调用UpdateShowMarkers()
,在那里我更新了state showMarkers
。状态会更新,但我的地图中的标记不会更新(在加载时会过滤标记,仅会创建匹配项)。然后,该状态被更新,但是没有任何意外发生。我不知道该怎么办。
我将不胜感激。
App.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import logo from './logo.svg';
import './App.css';
import Map from './map';
import Test from './test';
import InfoWindowD from './InfoWindowD'
class App extends Component {
constructor() {
super();
// this.child = React.createRef();
}
state= {
markers:
[ {
name: 'Стадион «Нижний Новгород»',
lat: 56.337498,
lng: 43.963386,
venueId: '555eed18498e3451c8bf5765',
type:'Sport'},
{
name: 'Большая Покровская улица',
lat: 56.317676,
lng: 43.995474,
venueId: '4bd322019854d13ae2f1fc4d',
type:'Entertaiment'},
{
name: 'Теннис Парк',
lat: 56.292484,
lng: 43.974676,
venueId: '54a6a2a6498ee573efdc4234',
type: 'Cafe'}
],
showMarkers: 'Sport'
}
//update showMarkers state
updateShowMarkers = (placeType) => {
console.log('updating the state showMarkers with value: ' + placeType)
// this.child.current.filterr(); this doesnt work
this.setState({showMarkers: placeType})
}
ejecutar = () => {
console.log('ejecutando')
// marker.setMap(null);
}
render() {
return (
<div>
<InfoWindowD markers={this.state.markers} UpdateShowMarkers={this.updateShowMarkers} showMarkers={this.state.showMarkers} filterMarkers={this.filterMarkers} ejecutar={this.ejecutar} />
<Test />
<Map
//ref={this.child}
id="CenterNN"
options={{
center: { lat: 56.327114, lng: 44.005632 },
zoom: 13
}}
onMapLoad={map => {
var markerDetails = this.state.markers;
for(var i = 0; i < markerDetails.length; i++ ) {
//console.log('loop ' + i)
var contentString = '<div>'+
'<p>Information is loading</p>'+
'</div>';
var infoWindow = new window.google.maps.InfoWindow({
content: contentString
});
var position = new window.google.maps.LatLng(markerDetails[i].lat, markerDetails[i].lng);
console.log('a: ' + this.state.showMarkers + ' b: '+markerDetails[i].type)
if( this.state.showMarkers === markerDetails[i].type ) {
var marker = new window.google.maps.Marker({
position: position,
// map: map, //set the markers in the map. below it was replaced
title: markerDetails[i].name
});
// add markers to the map
console.log('setting marker ' + markerDetails[i].type)
marker.setMap(map);
// }
console.log('continue the loop with ' + markerDetails[i].type)
// else if(this.state.showMarkers === 'deleteall') {
// marker.setMap(null);
// }
//to remove markers from map use the next line
//marker.setMap(null);
var e;
var filterMarkers = (e) => {
console.log('filtering markers')
// marker.setMap(null);
}
var filterr = () => {
console.log('filtering markers')
}
var venueInfo;
var attractionTitle;
// This request is not premium and is almost not limited to make tests per day
var foursquareVenue = (venueCode) => {
fetch(`https://api.foursquare.com/v2/venues/${venueCode}/likes?client_id=CID&client_secret=CSECRET&v=20180818`)
.then((result) =>
result.json()
)
.then(parsedJSON =>
(this.setState({attractions: parsedJSON.response}))
)
.then( ()=>
infoWindow.setContent(`<div><h2>${attractionTitle}</h2>
Likes: ${getAttractionLikes()}<br>
</div>`)
)
.catch((error) =>
console.log('There was a problem:' + error)
);
}
//this function can access the parent state
var getVenueDescription = () => {
if(!this.state.attractions.venue.description) {
return ('Description is not available for this place')
}
else{
return ( this.state.attractions.venue.description)
}
}
var getAttractionType = () => {
return ( this.state.attractions.venue.categories[0].name )
}
var getAttractionRating = () => {
return ( this.state.attractions.venue.rating )
}
var getAttractionAddress = () => {
return ( this.state.attractions.venue.location.address )
}
var getAttractionLikes = () => {
return ( this.state.attractions.likes.count )
}
// Allow each marker to have an info window
window.google.maps.event.addListener(marker, 'click', (function(marker, i, ) {
return function() {
attractionTitle= markerDetails[i].name;
var uniCode= markerDetails[i].venueId;
//ejecutar la funcion foursquareVenue y pasarle una variable clave para buscar el venue necesitado
{foursquareVenue(markerDetails[i].venueId, attractionTitle)}
infoWindow.open(map, marker)
}
})(marker, i));
}
} // ends if from line 110
}
}
/>
</div>
);
}
}
export default App;
map.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import InfoWindowD from './InfoWindowD'
const styles = {
width: '100%', height: '100%', position: 'absolute',
}
class Map extends Component {
constructor(props) {
super(props);
this.onScriptLoad = this.onScriptLoad.bind(this)
}
onScriptLoad() {
const map = new window.google.maps.Map(
document.getElementById(this.props.id),
this.props.options);
this.props.onMapLoad(map)
}
componentDidMount() {
if (!window.google) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = `https://maps.google.com/maps/api/js?key=AIzaSyDyeZwrmykBXkG_FkJY6kPthSpdidMpFiM`;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
//We cannot access google.maps until it's finished loading
s.addEventListener('load', e => {
this.onScriptLoad()
})
} else {
this.onScriptLoad()
}
}
render() {
return (
<div state= {this.state} style={styles} id={this.props.id} />
);
}
}
export default Map
//based on http://cuneyt.aliustaoglu.biz/en/using-google-maps-in-react-without-custom-libraries/
InfoWindow.js
import React from 'react';
import App from './App';
import Info from './Info'
const styles = {
position: 'inherit', backgroundColor: 'white',
}
function InfoWindowD(props) {
const { markers, infoWindow, filterMarkers, initialMarkers, ejecutar, map, newValue, updateShowMarkers, showMarkers } = props;
props.markers.map((myMarker) => {
if(myMarker.type === props.showMarkers) {
console.log('inside ' + myMarker.name)
}
console.log('with map ' + myMarker.name)
})
return (
<div style={styles}>
<div>
<Info newValue={props.newValue} />{props.showMarkers}
<div />
<div className="content">
<h3>Attractions type</h3>
<select defaultValue="all" onChange={(event)=>{props.UpdateShowMarkers(event.target.value), props.ejecutar(); }} >
<option value="all">All</option>
<option value="deleteall">deleteall</option>
{ props.markers.map((place) => {
return <option value={place.type}>{place.type}</option>
})
}
</select>
</div>
</div>
</div>
);
}
export default InfoWindowD;
非常感谢