Карты Google не определены, когда я перезагружаю страницу из-за проблем с загрузкой скриптов, как я могу это исправить? - PullRequest
0 голосов
/ 08 апреля 2020

Я реализовал Google Maps API на своей странице, и он отлично работает , за исключением , когда я делаю refre sh экрана.

Как только я нажимаю refre sh , Я получаю эту ошибку типа:

Cannot read property of maps, undefined

В частности, это происходит вокруг строки 28 в классе Map.

Здесь я устанавливаю сценарий для своего API, и когда я проверяю страницу, я вижу, что она присутствует (даже когда я обновляю sh страницу):

class App extends Component {
    // Render a script tag for scriptUrl in head of the HTML page
    addScriptToPage(scriptUrl) {
        const script = document.createElement("script");
        script.src = scriptUrl;
        document.head.appendChild(script);
    }

    componentDidMount() {
        // CreateReactApp requires the REACT_APP_ prefix for env vars
        let MAPS_API_KEY = process.env.REACT_APP_MAPS_API_KEY;
        // place the google maps api as a script tag in the head
        // this script places a google object on window.google
        let mapsApiUrl = `https://maps.googleapis.com/maps/api/js?key=${MAPS_API_KEY}`;
        this.addScriptToPage(mapsApiUrl);
    }

    render() {
        return (
        <div className='app-wrapper'>
            <Modal />
            <NavBarContainer />

            <div className="app-main-content-wrapper">
              <Switch>
                <Route exact path='/' component={SpotIndex} />
                <Route exact path='/spots/:spotId' component={SpotDetail} />
                        <Route exact path='/search/:find_loc' component={SearchContainer} />
              </Switch> 
            </div>
        </div>
        );
    }
};

И это мой класс Map:

class Map extends Component {
  constructor(props) {
    super(props);
  }

  // Initially mounts the map with first search input
  componentDidMount() {
    this.drawMap(this.props.find_loc);
  } 

  componentWillReceiveProps(newProps) {
    this.drawMap(newProps.find_loc);
  }

  drawMap(address) {
    // Solves problem of linting rule in ReactJS that forbids unknown global vars
    const google = window.google;
    const map = document.getElementById('map-container');

    // Creating the map
    MapUtil.setOptionsFromLocation(address)
      .then(options => {
        this.map = new google.maps.Map(map, options);

        // before adding markers, set up bounds
        let bounds = new google.maps.LatLngBounds();

        // Displaying nearby spots
        this.props.spots.forEach(spot => {
          // Create a position from spot coordinates
          const latitude = spot.latitude;
          const longitude = spot.longitude;
          const position = new google.maps.LatLng(latitude, longitude);

          // Place markers on the map
          const marker = new google.maps.Marker({
            position,
            map: this.map
          });

          // extend the bounds to fit this position
          bounds.extend(position);
        });

        // Autozooming and autocentering if there are results
        if (this.props.spots.length) {
          // Autozooming
          this.map.fitBounds(bounds);

          // Adjust zooming value if too large
          let theMap = this.map;
          var listener = google.maps.event.addListener(theMap, "idle", function () {
            if (theMap.getZoom() > 16) theMap.setZoom(16);
            google.maps.event.removeListener(listener);
          });

          // Autocentering
          this.map.panToBounds(bounds);
        }
      });
  }

  // Renders Map component
  render() {
    return <div id="map-container"></div>;
  }
}

Согласно приведенным ниже советам, похоже, что ошибка не в вышеуказанных компонентах. Выполняя некоторые раскопки, я нашел другое место, где я вызываю компонент Map.

Это общий компонент поиска, который отображает Map и SearchIndex (результаты поиска):

class Search extends React.Component {
    constructor(props) {
        super(props);
        this.state = { find_loc: this.props.find_loc };
    }

    // Triggers a re-render when component receives new props
    componentWillReceiveProps(newProps) {
    this.setState({ find_loc: newProps.match.params.find_loc });
    }

    // Gets spots matching search input
    getSpots(spots) {
        // Library of state abbreviations
        const states = {
            "AL": "alabama",
            "AK": "alaska",
            "AS": "american samoa",
            "AZ": "arizona",
            "AR": "arkansas",
            "CA": "california",
            "CO": "colorado",
            "CT": "connecticut",
            "DE": "delaware",
            "DC": "district of columbia",
            "FL": "florida",
            "GA": "georgia",
            "GU": "guam",
            "HI": "hawaii",
            "ID": "idaho",
            "IL": "illinois",
            "IN": "indiana",
            "IA": "iowa",
            "KS": "kansas",
            "KY": "kentucky",
            "LA": "louisiana",
            "ME": "maine",
            "MD": "maryland",
            "MA": "massachusetts",
            "MI": "michigan",
            "MN": "minnesota",
            "MS": "mississippi",
            "MO": "missouri",
            "MT": "montana",
            "NE": "nebraska",
            "NV": "nevada",
            "NH": "new hampshire",
            "NJ": "new jersey",
            "NM": "new mexico",
            "NY": "new york",
            "NC": "north carolina",
            "ND": "north dakota",
            "OH": "ohio",
            "OK": "oklahoma",
            "OR": "oregon",
            "PA": "pennsylvania",
            "PR": "puerto rico",
            "RI": "rhode island",
            "SC": "south carolina",
            "SD": "south dakota",
            "TN": "tennessee",
            "TX": "texas",
            "UT": "utah",
            "VT": "vermont",
            "VI": "virgin Islands",
            "VA": "virginia",
            "WA": "washington",
            "WV": "west Virginia",
            "WI": "wisconsin",
            "WY": "wyoming"
        }

        // Getting lowercased location string from search input
        const location = this.state.find_loc;
        let locationArr;
        let lowercasedLocation = [];
        let foundSpots = [];

        if (location) {
            locationArr = location.split(' ');
            locationArr.forEach(word => lowercasedLocation.push(word.toLowerCase()));
            lowercasedLocation = lowercasedLocation.join(' ');
        }

        // Searching for spots matching location
        spots.forEach(spot => {
            const city = spot.city.toLowerCase();
            const stateAbbr = spot.state.toLowerCase();
            const stateFull = states[spot.state];

            if (city === lowercasedLocation || stateAbbr === lowercasedLocation || stateFull === lowercasedLocation) {
                foundSpots.push(spot);
            }
        });

        return foundSpots;
    }

    // Renders Search component
    render() {
        const { spots } = this.props;
        const foundSpots = this.getSpots(spots);

        return (
            <div className="search-container">
                <div className="search-results-wrapper">
                  <SearchIndex spots={foundSpots} find_loc={this.state.find_loc} fetchSpots={this.props.fetchSpots} />
                    <Map spots={foundSpots} find_loc={this.state.find_loc} />  
                </div>

                <Footer />
            </div>
        );
    }
}

У меня была похожая проблема с загрузкой SearchIndex ранее , из-за того, что spots не загружается при перезагрузке страницы. Но я решил эту проблему, явно указав компоненту SearchIndex, чтобы он извлекал все точки, когда компонент был смонтирован; Я думаю, что, возможно, это может быть похожая проблема для карты (в частности, window.google)?

1 Ответ

0 голосов
/ 08 апреля 2020

Добавить слушателя для события tilesloaded:

this.map = new google.maps.Map(map, options);

this.map.addListener('tilesloaded', function () {

  ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...