首页 > 解决方案 > 实现承诺后让标记显示在谷歌地图上?

问题描述

好的,所以我在我的项目中被困在这一点上,我创建了一个谷歌地图,并且能够使用foursquare获取一堆位置并将它们变成我的地图的标记,问题是标记最初没有加载并且只会在使用搜索功能后显示,我知道我正在异步获取信息,但不知道如何告诉代码在履行承诺后立即加载标记。这是代码。

import React, { Component } from 'react';
import { Map, InfoWindow, Marker, GoogleApiWrapper} from 'google-maps react';
import axios from 'axios';

var  AllPlaces = [

]


axios.get("https://api.foursquare.com/v2/venues/search?ll=40.7589,-73.9851&query=food&radius=2000&categoryId=4d4b7105d754a06374d81259&client_id=API&client_secret=API&v=20201215&limit=6").then(
response => {
response.data.response.venues.forEach(function(item){
  AllPlaces.push(
    {
      name: item.categories[0].name.toLowerCase(),
      lat: item.location.lat,
      lng: item.location.lng
    }
  )
})
}
)


class MapContainer extends Component {
state = {
showingInfoWindow: false,
activeMarker: {},
selectedPlace: {},
query:'',
filteredPlaces: []
};

markers = []


onMarkerClick = (props, marker, e) => {
this.setState({
selectedPlace: props,
activeMarker: marker,
showingInfoWindow: true
});
}

onLiClick = (i) =>{
this.setState({
showingInfoWindow: true,
activeMarker: this.markers[i],
selectedPlace: AllPlaces[i]
})
}


onMapClicked = (props) => {
if (this.state.showingInfoWindow) {
this.setState({
showingInfoWindow: false,
activeMarker: null
})
}
}


CreateInputField = () => (
<input
placeholder = "Search Nearby Places"
onChange={(event) => this.setState({filteredPlaces: AllPlaces.filter(place => !place.name.startsWith((event.target.value).toLowerCase()))})}
/>
)

render() {
return (
<div className = 'map-container' role='application' style=
{{marginleft:'250px'}}>
<div>
  <div className = 'navMenu'>
    <div className = 'List'>
      <h1 className = 'title'> Places to Eat
</h1>
        {this.CreateInputField()}
    </div>
    <div className = 'PlaceList'>
      <ol className='Places'>
        {AllPlaces.map((arrayItem, index)=>
        !this.state.filteredPlaces.includes(arrayItem) &&
          <li
          key = {index}
          className='Place'
          onClick={() => {this.onLiClick(index)}}
          >{arrayItem.name}</li>
        )}
      </ol>
    </div>
  </div>
</div>
<Map google={this.props.google} zoom={14}
  initialCenter = {{lat:40.7589, lng:-73.9851}}
  onClick={this.onMapClicked}>
  {AllPlaces.map((marker, i) =>
    !this.state.filteredPlaces.includes(marker) &&
      <Marker
      ref={(e) => {if (e) this.markers[i] = e.marker}}
      onClick={this.onMarkerClick}
      title = {marker.name}
      key = {i}
      name={marker.name}
      position =
 {{lat:marker.lat,lng:marker.lng}}
      />
  )}
  <InfoWindow
    onOpen={this.windowHasOpened}
    onClose={this.windowHasClosed}
    marker={this.state.activeMarker}
    visible={this.state.showingInfoWindow}>
    <div>
      <h1>{this.state.selectedPlace.name}</h1>
    </div>
  </InfoWindow>
 </Map>
 </div>
);
}
}

export default GoogleApiWrapper({
apiKey: 'KEY'
})(MapContainer)

标签: javascriptreactjs

解决方案


在组件本身内部执行异步请求,然后将该新值放入组件状态。React 会知道当状态改变时要重新渲染,所以你只需要担心管理状态。Async / await 语法也使它更干净

例如

class MapContainer extends Component {

  async componentWillMount() {
    const axiosData = await axios
      .get(
        'https://api.foursquare.com/v2/venues/search?ll=40.7589,-73.9851&query=food&radius=2000&categoryId=4d4b7105d754a06374d81259&client_id=API&client_secret=API&v=20201215&limit=6'
      )
      .then(response =>
        response.data.response.venues.map(v => ({
          name: v.categories[0].name.toLowerCase(),
          lat: v.location.lat,
          lng: v.location.lng,
        }))
      );
    this.setState({axiosData})  
  }

推荐阅读