карта не определена, и я не уверен, это свойство или моя настройка api - PullRequest
0 голосов
/ 17 июня 2020

Я постоянно получаю следующую ошибку при внедрении API карт Google. Я слежу за учебником на YouTube и адаптирую его к своему коду. Две основные проблемы: во-первых, свойство карты не определено. Во-вторых, я не уверен, правильно ли работает мой URL-адрес API Google для mapData. Любая помощь будет принята с благодарностью.

×
TypeError: Cannot read property 'map' of undefined
Map
C:/Users/Langley/Desktop/ArticCards/screens/MapScreen.js:18
  15 |  const [selectedSpeech, setSelectedSpeech] = useState(null);
  16 | 
  17 |  return(
> 18 |    <GoogleMap
     | ^  19 |      defaultZoom={10} defaultCenter={{lat: 42.807091, lng: -86.018860}}
  20 |    >
  21 |      {mapData.results.map((speech) => (

MapScreen

import React, { useState, useEffect } from "react";
import {
    withGoogleMap,
    withScriptjs,
    GoogleMap,
    Marker,
    InfoWindow
  } from "react-google-maps";
import {getMap} from '../api/gmap';
import {gkey} from '../api/gkey'

const mapData = getMap();

function Map(){
  const [selectedSpeech, setSelectedSpeech] = useState(null);

  return(
    <GoogleMap
      defaultZoom={10} defaultCenter={{lat: 42.807091, lng: -86.018860}}
    >
      {mapData.results.map((speech) => (
        <Marker key={speech.place_id} position={{
          lat: speech.geometry.location.lat, 
          lng: speech.geometry.location.lng
        }}
        onPress={() => {
          setSelectedSpeech(speech);
        }}
        />
      ))}

      {selectedSpeech && (
        <InfoWindow position={{
          lat: selectedSpeech.geometry.location.lat, 
          lng: selectedSpeech.geometry.location.lng
        }}
        onCloseClick={() => {
          setSelectedSpeech(null);
        }}
        >
          <div> 
            <h2>
              {selectedSpeech.name}
            </h2>
            <h3>
              {selectedSpeech.rating}
            </h3>
            <p>
              {selectedSpeech.formatted_address}
            </p>
          </div> 
        </InfoWindow>
      )}
    </GoogleMap>
  );
}

const WrappedMap = withScriptjs(withGoogleMap(Map));

const MapScreen = () => {
  return(
    <div style={{width: '100vw', height: '100vh'}}>
      <WrappedMap googleMapURL={`https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places&key=${gkey}`}
        loadingElement = {<div style={{height: "100%"}}/>}
        containerElement = {<div style={{height: "100%"}}/>}
        mapElement = {<div style={{height: "100%"}}/>}
      />
    </div>
  )
}

export default MapScreen;

gmap. js

import axios from 'axios'
import {gkey} from './gkey';

const gmapServer = axios.create({
    baseURL:'http://maps.googleapis.com/'

})


export const getMap = async (callback) => {
    const response = await gmapServer.get(
        `maps/api/place/textsearch/json?query=speech+pathologists&key=${gkey}`
    ); 
    callback(response.data)
};

1 Ответ

1 голос
/ 18 июня 2020
  • посмотрите на свой getMap и как он реализован. он ничего не возвращает, он ожидает получить обработчик обратного вызова для получения response.data. это вариант реализации для передачи обратного вызова. Напротив, вы можете вернуть response.data, но это еще одна тема c обсуждения;

  • ваш gmap, который является вызовом asyn c, должен вызываться в жизненном цикле реакции (предпочтительно на Mount) и правильно установите состояние. учитывая, что вы используете хуки, useEffect должно сработать. (вам нужно будет передать пустой массив в качестве второго аргумента, чтобы запускаться только при монтировании)

  • , так как это асинхронный c вызов при первом рендеринге mapData.results не будет существовать, поэтому вы можно использовать &&, который действует как короткое замыкание, которое позволяет избежать выполнения второй части, если первая оценивается как ложь.

, учитывая, что ваш код может быть более близок к:

function Map(){
  const [selectedSpeech, setSelectedSpeech] = useState(null);
  const [mapData, setSMapData] = useState(null);

  useEffect(() => {
    // setSMapData will be called with results.data updating mapData
    getMap(setSMapData)
  }), [])

  return(
    <GoogleMap
      defaultZoom={10} defaultCenter={{lat: 42.807091, lng: -86.018860}}
    >
      {mapData && mapData.results.map((speech) => (
        <Marker key={speech.place_id} position={{
          lat: speech.geometry.location.lat, 
          lng: speech.geometry.location.lng
        }}
        onPress={() => {
          setSelectedSpeech(speech);
        }}
        />
      ))}

      // rest of code
...