Google Maps Api: функция map () не возвращает маркеры - PullRequest
1 голос
/ 26 января 2020

Я использую API землетрясения, чтобы получить это JsonData с «response- google-maps" ( Do c). Но почему-то маркеры не появляются, и я не понимаю, почему.

const url =
  "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_day.geojson";

const Map = () => {
  const defaultCoordinate = { lat: -0.8962, lng: -91.4445 }; 

  const getMarkers = () => {
    FetchEarthquakeData(url).then(result => {
      console.log(result.features);                     //LOG1
      result.features.map(earthquake => (
        console.log(earthquake),                        //LOG2
        <Marker
          key={earthquake.id}
          position={{
            lat: earthquake.geometry.coordinates[1],
            lng: earthquake.geometry.coordinates[0]
          }}
        />
      ));
    });
  };

  return (
    <GoogleMap defaultCenter={defaultCoordinate} defaultZoom={8}>
      {getMarkers()}
    </GoogleMap>
  );
};

const WrappedMap = withScriptjs(withGoogleMap(Map));

Первый console.log (LOG1) возвращает массив из JsonData. LOG 2 возвращает каждый отдельный объект массива. В консоли нет ошибок.

1 Ответ

1 голос
/ 26 января 2020

Вам необходимо добавить оператор return к getMarkers (и один к обратному вызову .then). (Но это не единственная проблема здесь, смотрите после следующего блока кода больше)

Проблема не в том, что .map ничего не возвращает, а в том, что getMarkers не возвращает вывод из .map.

Обновлено getMarkers:

const getMarkers = () => {
  return FetchEarthquakeData(url).then(result => {
    console.log(result.features);                     //LOG1
    return result.features.map(earthquake => (
      console.log(earthquake),                        //LOG2
      <Marker
        key={earthquake.id}
        position={{
          lat: earthquake.geometry.coordinates[1],
          lng: earthquake.geometry.coordinates[0]
        }}
      />
    ));
  });
};

Однако getMarkers является асинхронной функцией, поэтому вы не можете использовать ее вывод непосредственно при рендеринге. функция (или тело функционального компонента). Вместо этого вы должны хранить данные из FetchEarthquakeData в переменной состояния и затем извлекать из состояния при рендеринге. Вы также можете добавить состояние загрузки при извлечении данных о землетрясении.

Например:

const url =
  "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_day.geojson";

const Map = () => {
  const defaultCoordinate = { lat: -0.8962, lng: -91.4445 };

  const [isLoading, setIsLoading] = React.useState(true);
  const [earthquakes, setEarthquakes] = React.useState([]);

  React.useEffect(() => {
    (async () => {
      setIsLoading(true);

      const result = await FetchEarthquakeData(url);
      console.log(result.features); // LOG1
      setEarthquakes(result.features);

      setIsLoading(false);
    })();
  }, []);

  if (isLoading) {
    return "loading...";
  }

  const markers = earthquakes.map(earthquake => (
    console.log(earthquake), // LOG2
    <Marker
      key={earthquake.id}
      position={{
        lat: earthquake.geometry.coordinates[1],
        lng: earthquake.geometry.coordinates[0]
      }}
    />
  ));

  return (
    <GoogleMap defaultCenter={defaultCoordinate} defaultZoom={8}>
      { markers }
    </GoogleMap>
  );
};

const WrappedMap = withScriptjs(withGoogleMap(Map));

Обратите внимание, что здесь мы отделяем логи выборки данных c от логи визуализации c и сохраните извлеченные данные в состоянии компонента, затем просто возьмите данные из состояния при рендеринге.

Также синтаксис useEffect может выглядеть немного странно, но это необходимо только потому, что обратный вызов, переданный в useEffect, не может быть асинхронным, поэтому мы создаем анонимную асинхронную функцию и немедленно ее вызываем.

...