首页 > 解决方案 > TypeError:无法读取反应中未定义的属性“过滤器”

问题描述

每当我单击 li 上的项目时,我的 clickHandler 函数都会引发错误 - TypeError: Cannot read property 'filter' of undefined。每当用户单击侧边栏上的项目时,我都会创建一个功能,即 InfoWindow 弹出窗口。但是在我的代码中看不到问题。

这是我的 App.js 代码:

  import React, { Component } from 'react';
    //import logo from './logo.svg';
    import './App.css';
    import axios from 'axios';
    //import SideBar from './components/SideBar';


    class App extends Component {

      constructor(props){
        super(props);
        this.state = {
          venues: [],
          markers: [],
          InfoWindow: [],
          map: [],
        }
        //this.clickHandler = this.clickHandler.bind(this);
      }

      componentDidMount(){
        this.getVenues()
        console.log("component did mount")
      }

      Map = () => {
        loadMapUrl();
        window.initMap = this.initMap;
      }

      initMap = () => {
        // Constructor creates a new map - only center and zoom are required.
         const map = new window.google.maps.Map(document.getElementById('map'), {
          center: {lat: 40.730610, lng: -73.935242},
          zoom: 14,
          mapTypeControl: true
        });

        const bounds = new window.google.maps.LatLngBounds();
        const InfoWindow = new window.google.maps.InfoWindow();

        //Ploting marker on the map using map function
         let markers = [];
         let venuesInfo = [];
        this.state.venues.map(myVenue => { 
          //const title = `${myVenue.venues.name}`; 
          //Content String Reference https://developers.google.com/maps/documentation/javascript/infowindows
          //const address = myVenue.venue.location.address;
          //const name = myVenue.venue.name;
          const contentString = `<div><h3>${myVenue.venue.name.toUpperCase()}</h3>
                                <h5>Address: ${myVenue.venue.location.address}</h5>
                                <h5>Location: ${myVenue.venue.location.city}, ${myVenue.venue.location.state} </h5>
                                <h5>Pincode:${myVenue.venue.location.postalCode}</h5>
                                <p><strong> ${'<a href="https://foursquare.com/v/' + myVenue.venue.id + '" target="_blank">Click Here For More Info</a>'} </strong> </p></div>`
          // Creating marker
          //const venues =[];
          const marker = new window.google.maps.Marker({
            map: map,
            position: {lat: myVenue.venue.location.lat, lng: myVenue.venue.location.lng},
            animation: window.google.maps.Animation.DROP,
            name: myVenue.name,
            id: myVenue.id,
            });

            marker.addListener('click', () => {
              if(marker.getAnimation() !== null){marker.setAnimation(null);}
              else{marker.setAnimation(window.google.maps.Animation.BOUNCE);}
              setTimeout(function(){ marker.setAnimation(null) }, 1500)
            });

              window.google.maps.event.addListener(marker, 'click', () => {
              // Putting all the content on the map
              InfoWindow.setContent(contentString)
              //Centering the position of the map according to the marker
              map.setCenter(marker.position);

              InfoWindow.open(map, marker);
            });

            markers.push(marker);
            venuesInfo.push({id: myVenue.venue.id, name:myVenue.venue.name, contents: contentString})

            bounds.extend(marker.getPosition());
            //Adding listener to the marker
            map.fitBounds(bounds);
            this.setState({
              map: map,
              markers: markers,
              InfoWindow: InfoWindow,
              venues: venuesInfo
              });

          return myVenue.marker;

        });
      }

**//This is the arrow function**
      clickHandler = (venues) => {
        let marker = this.markers.filter(m => m.id === venues.id);
          // Putting all the content on the map
          this.state.InfoWindow.setContent(marker.contents)
          //Centering the position of the map according to the marker
         // this.state.map.setCenter(this.marker.position);
         this.state.InfoWindow.open(this.map, marker);
        console.log(marker)
      }

      //Fetching places information using Foursquare API
        getVenues = () => {
          const endPoint = "https://api.foursquare.com/v2/venues/explore?"
          const credentials = {
            client_id: "ZAM2ZVYH1W4E5KRSTWM140LP5UWX20J5XHK4NAUJLO5CJUNH",
            client_secret: "CZTDHFFXI4SXYOXAN41MCUG2PPDEDIAATTCVRC1FUMGOSI1C",
            query: "Food",
            near: "New York", 
            v: "20181107",
            limit:10,
          }

          //Promise based HTTP client for the browser
          axios.get(endPoint + new URLSearchParams(credentials))
          .then(response => {
            this.setState({
              venues: response.data.response.groups[0].items
            }, this.Map() )//callback function
          })
          .catch(error =>{
            alert('Error Occured While Fetching Foursquare API' + error);
          })
        }


      render() {
        return (
         <main id="App">
          <div id="sideBar">
                <div id="heading">
                <h2>Food Places</h2>
                <div id="search">
                <input type="text" placeholder="Search.." aria-labelledby="filter" ></input>
                </div>
                </div>
                {this.state.venues  && this.state.venues.map((venue, id) => ( 
                  <div key={id} id="venueList"  onClick={() => {this.clickHandler(venue)}}>
                   <ul id="listItem">
                  <li>
                   {venue.name}
                  </li>
                  </ul>
                  </div>
                 ))}
                </div>
           <div id="map">
           </div>
         </main>
        );
      }

    }
    // This function will generate script tag and will insert the google map API URL Dynamically.
    function loadMapUrl(){
      const scriptTag = window.document.createElement('script');
      const apiKey = 'AIzaSyASFSGSrxEXyjwZSqMyzRJBbfq_eFutui8';
      scriptTag.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&callback=initMap`;
      scriptTag.async = true;
      scriptTag.defer = true;
      document.body.appendChild(scriptTag);
    }

    export default App;

标签: reactjs

解决方案


显然你想使用this.state.markers而不是this.markers.

但是,您的整个状态处理是有问题的。你甚至没有打电话就改变了状态setState


推荐阅读