我正在尝试使用从 Foursquare API 获取的位置创建地图,位置在应用程序中以两种方式显示,作为包含列表项(位置名称(和地图标记的侧边栏,有一个搜索框,根据此搜索框上的查询,应过滤数据,以便过滤位置和标记以同时匹配查询, 现在我正确过滤了位置列表,但没有在地图上的标记
这是父组件
import React, { Component } from 'react';
import Map from './Map';
import List from './List'
import escapeRegExp from 'escape-string-
regexp';
import './App.css';
class App extends Component {
state = {
places: [],
query: '',
}
componentDidMount() {
this.fetchPlaces();
}
fetchPlaces() {
const client_id = "N4UIDVOE5XA3YVMBMMLIANAYLDEGSTDJY3KLFM0BAQJB1A4G" ;
const client_secret = "RVWSHIZAAKLLTW03ELYCPVY1GJ1QZ312AP0C1MLOCBP5JG4Q";
const api = "https://api.foursquare.com";
const request = fetch(`${api}/v2/venues/search?ll=30.044281,31.224291&categoryId=4bf58dd8d48988d181941735,4bf58dd8d48988d181941735,4bf58dd8d48988d13a941735&client_id=${client_id}&client_secret=${client_secret}&v=20180719`);
return request.then(response => {
//MDN
const myOk = response.ok;
if(myOk) {
return response.json();
}
}).then(places => {
this.setState({places: places.response.venues});
//on error fetching locations
}).catch(() => alert('error fetching data'));
}
updateQuery = (query) => {
this.setState({query})
}
render() {
const { places, query} = this.state;
let placesToShow;
if(query) {
const match = new RegExp(escapeRegExp(query), 'i');
placesToShow = places.filter(place => match.test(place.name));
}
else {
placesToShow = places;
}
return (
<div className="app">
<Map places={ placesToShow }/>
<List places ={ placesToShow }
onUpdateQuery={ this.updateQuery }/>
</div>
);
}
}
导出默认应用程序;
这是子组件
import React, { Component } from 'react';
class Map extends Component {
componentDidMount() {
//getting the script of the map
const script = document.getElementsByTagName('script')[0];
//load the map after the script loads
script.addEventListener('load', e => {this.initMap()});
}
initMap() {
const container = document.getElementById('map');
const map = new
window.google.maps.Map(container, {
center: { lat: 30.044281, lng: 31.224291 },
});
this.setState({ map });
}
createMarkers() {
const { map } = this.state;
const markers =
this.props.places.map(place => { return (new window.google.maps.Marker({
position: {lat: place.location.lat, lng: place.location.lng},
name: place.name,
map: map,
}));
})
const bounds = new window.google.maps.LatLngBounds();
const largeInfoWindow = new window.google.maps.InfoWindow();
markers.forEach(marker => {
bounds.extend(marker.position);
marker.addListener('click', e => {
largeInfoWindow.setContent(`<div>${marker.name }</div>`);
largeInfoWindow.open(map, marker);
});
})
map.fitBounds(bounds);
}
componentDidUpdate() {
this.createMarkers();
}
render(){
return(
<div id="map" />
);
}
}
export default Map;
那么为什么标记没有正确过滤,以及如何实现这一点???
编辑
在我将所有标记映射设置为空后,仅添加过滤的标记后,它起作用了
componentDidUpdate(prevProps, prevState) {
if(prevProps.places !== this.props.places) {
this.state.markers.forEach(marker => marker.setMap(null))
this.createMarkers();
}
}
我认为问题是您的createMarkers
函数不会删除标记。它只附加新的标记,也可能复制它们。简单的方法是使用此处所述的marker.setMap(null)
在createMarkers
开始时删除所有标记。但是,这不是最有效的解决方案,因为您可以将以前的标记与新标记进行比较,并且仅在必要时进行调整。或者,您可以利用react-google-maps库为您处理标记。