【问题标题】:React get object-values outside of .then // create map markers out of geocodesReact 在 .then 之外获取对象值 // 从地理编码中创建地图标记
【发布时间】:2019-11-23 09:12:50
【问题描述】:

我评论了我的代码以明确应该发生什么。我尝试了几个小时从地理编码中创建标记,但是我似乎无法弄清楚如何从承诺中提取值。我摆弄了 useState 和 useEffect,但都没有用。

const GMap = eventList => {
  return (
    <GoogleMap defaultZoom={10} defaultCenter={{ lat: 51.62919, lng: 7.3928 }}>
      {
          // Map through location-strings in eventList
          eventList.eventList.map(event => {
              // Get all geocodes
        Geocode.fromAddress(event.city).then(
          response => {
            const { lat, lng } = response.results[0].geometry.location;
            console.log(lat, lng);
          },
          error => {
            console.error(error);
          }
        );
        return (
            // Create marker for every geocode (lat/lng pair)
          <Marker
            key={event._id}
            position={{
              lat: 51.62919, // How to insert the lat and lng values from response instead?
              lng: 7.3928
            }}
          />
        );
      })}
    </GoogleMap>
  );
};

感谢您的帮助,尽管一开始看起来微不足道,但现在无法解决这个问题真的很令人沮丧。

【问题讨论】:

标签: reactjs promise maps marker geocode


【解决方案1】:
const GMap = ({ eventList }) => {
  const [markers, setMarkers] = React.useState([]);

  React.useEffect(() => {
    eventList.forEach(async event => {
      const response = await Geocode.fromAddress(event.city);
      const { lat, lng } = response.results[0].geometry.location;

      const marker = (
        <Marker
          key={event._id}
          position={{
            lat,
            lng
          }}
        />
      );

      setMarkers(prevMarkers => [...prevMarkers, marker]);
    });
  }, [eventList]);

  return (
    <GoogleMap defaultZoom={10} defaultCenter={{ lat: 51.62919, lng: 7.3928 }}>
      {markers}
    </GoogleMap>
  );
};
eventList.forEach(async event => {
      const response = await Geocode.fromAddress(event.city);

我们将遍历 eventList 并在每次 Geocode.fromAddress 返回时处理结果,而不是在 map 中执行。地图的问题是您限制自己在显示任何内容之前首先处理整个地图。此方法允许您在返回标记时对其进行渲染。

setMarkers(prevMarkers => [...prevMarkers, marker]);

使用useState 的回调,我们使用之前的markers 并创建一个新数组,将之前的标记附加到它上面,因此它会随着每个Geocode.fromAddress(event.city); 的返回而慢慢建立。

这里有一个工作的 CodeSandbox https://codesandbox.io/s/wizardly-paper-3eu03 我不得不删除GoogleMapMarkersGeocode

Geocode,为了模拟现实世界,有一个随机的setTimeout,所以你可以看到每个结果都准备好了。

【讨论】:

  • 非常感谢!这很好用,解释也非常有帮助和易于理解!
【解决方案2】:

您可以使用 async-await 从 Promise 同步获取响应:

eventList.eventList.map(async event => {
   // Get all geocodes
   const rs = await Geocode.fromAddress(event.city)

   // Path to location. this path example could be wrong
   const { lat, lng } = rs.results[0].geometry.location 

   return (
      <Marker
          key={event._id}
          position={{
              lat: lat,
              lng: lng
         }}
      />
   );
})

【讨论】:

  • 谢谢@jdn。它还没有工作。我收到多个错误: 1. 警告:列表中的每个孩子都应该有一个唯一的“关键”道具。检查Events的渲染方法。 2. react-dom.development.js:14793 Uncaught Error: Objects are not valid as a React child (found: [object Promise])。如果您打算渲染一组子项,请改用数组 3. event.js:46 Uncaught (in promise) TypeError: Cannot read property 'statusText' of undefined (at event.js:46)
  • 这也是: 4. index.js:1375 警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请在 componentWillUnmount 方法中取消所有订阅和异步任务。
猜你喜欢
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 2020-01-16
  • 1970-01-01
  • 2018-01-14
  • 2015-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多