【问题标题】:Google Maps Api: The map() function doesnt return MarkersGoogle Maps Api:map() 函数不返回标记
【发布时间】:2020-01-26 00:07:18
【问题描述】:

我正在使用地震 api 通过“react-google-maps”(Doc) 获取此 JsonData。 但不知何故,标记没有出现,我不明白为什么。

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 返回数组的每个对象。控制台中没有错误。

【问题讨论】:

  • 删除LOG2和逗号就可以了
  • getMarkers 没有返回任何内容,即使它返回了,您也正在尝试同步获取异步调用的结果。

标签: javascript reactjs asynchronous google-maps-api-3


【解决方案1】:

您需要向getMarkers 添加一条return 语句(并在.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));

注意这里我们把取数据逻辑和渲染逻辑分开,把取到的数据存放在组件的state中,然后在渲染的时候从state中取数据。

另外useEffect 的语法可能看起来有点奇怪,但这只是必要的,因为传递给useEffect 的回调不能是异步的,所以我们创建了一个匿名异步函数并立即调用它。

【讨论】:

  • 这解决了退货问题,但它仍然不起作用,因为现在getMarkers 返回一个Promise 而不是Marker 组件的数组。
  • @Titus 更新了答案,让我知道情况如何
  • 谢谢你们。我对钩子有同样的想法。我要玩弄代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多