为什么标记未正确过滤?

时间:2018-08-19 23:55:50

标签: reactjs google-maps

我正在尝试创建一个具有从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;

那为什么标记未正确过滤以及如何实现呢?

修改

在我将所有标记图都设置为null之后再仅添加过滤的标记图

componentDidUpdate(prevProps, prevState) {
  if(prevProps.places !== this.props.places) {
    this.state.markers.forEach(marker => marker.setMap(null))
    this.createMarkers(); 
  }
}

1 个答案:

答案 0 :(得分:2)

我认为问题在于您的createMarkers函数不会删除标记。它仅附加新标记,并且可能还会复制它们。容易做到的是,按照here所述,使用createMarkersmarker.setMap(null)的开头删除所有标记。但是,这并不是最有效的解决方案,因为您可以将以前的标记与新的标记进行比较,并仅在必要时进行调整。另外,您可以利用react-google-maps库来为您处理标记。