【问题标题】:Return a specific string from a Promise从 Promise 返回一个特定的字符串
【发布时间】:2021-05-17 02:44:09
【问题描述】:

我正在编写一个 React/Next.js 应用程序,并且我正在使用三词地址将项目映射到一个位置。我的代码接收三词地址,将其转换为坐标,然后应该在 Mapbox 地图上显示该位置。

const Item = () => {
  const location = "daring.lion.race";
  const api = require("@what3words/api");
  api.setOptions({ key: "my_api_key" });
  const data = api.convertToCoordinates(location).then((value) => {
    return value;
  });

  const [coords, setCoords] = useState();

  async function getCoords() {
    const jason = await data;
    console.log(jason);
    setCoords(jason);
  }

  getCoords();

  const [viewport, setViewport] = useState({
    width: 1000,
    height: 400,
    latitude: coords.coordinates.lat,
    longitude: coords.coordinates.lng,
    zoom: 16,
  });

  return (
    <div>
      <ReactMapGL
        mapStyle="mapbox://styles/mapbox/outdoors-v11"
        mapboxApiAccessToken="my_api_key"
        {...viewport}
       ></ReactMapGL>
    </div>
  );
};

what3words API 返回一个承诺:

{
  "country": "GB",
  "square": {
    "southwest": {
      "lng": -0.12552,
      "lat": 51.508328
    },
    "northeast": {
      "lng": -0.125477,
      "lat": 51.508355
    }
  },
  "nearestPlace": "London",
  "coordinates": {
    "lng": -0.125499,
    "lat": 51.508341
  },
  "words": "daring.lion.race",
  "language": "en",
  "map": "https://w3w.co/daring.lion.race"
}

我正在尝试将承诺中的坐标放入视口中,但它不起作用。我正在使用 ReactMapGL (http://visgl.github.io/react-map-gl/) 来显示 Mapbox 地图。

【问题讨论】:

    标签: javascript reactjs typescript async-await next.js


    【解决方案1】:

    getCoords异步,所以你不能调用它然后立即尝试使用它的结果。在异步操作之外,您可以将初始状态设置为一些默认值:

    const [viewport, setViewport] = useState({
      width: 1000,
      height: 400,
      latitude: 0,  // default value
      longitude: 0, // default value
      zoom: 16,
    });
    

    然后在您的异步操作中,在数据可用后,您可以使用这些值更新状态(就像您已经对 coords 状态所做的那样):

    async function getCoords() {
      const jason = await data;
      console.log(jason);
      setCoords(jason);
      // here:
      setViewport({
        ...viewport,
        latitude: jason.coordinates.lat,
        longitude: jason.coordinates.lng,
      });
    }
    

    请注意,在异步操作完成后,组件将使用默认值短暂呈现,然后使用更新的值重新呈现。如果不希望这样做,那么您也可以根据状态有条件地渲染。也许是这样的:

    return (
      <div>
        {
          viewport.latitude === 0 ?
          'Please wait...' :
          <ReactMapGL
            mapStyle="mapbox://styles/mapbox/outdoors-v11"
            mapboxApiAccessToken="my_api_key"
            {...viewport}
          ></ReactMapGL>
        }
      </div>
    );
    

    【讨论】:

    • 嗨,我试过了,它会正确地将jason 记录到控制台,但随后会报告coords未定义 的错误。我在没有setCoords 的情况下尝试了它,只使用了jason.coordinates.latjason.coordinates.lng,但它仍然返回undefined。有什么线索吗?
    • @edapm:那是我的错误,我忘记了设置状态也是异步的。我已经更新了代码。您想要的数据不是依赖于那条线上的坐标,而是在 jason 中。 (这意味着如果您只使用视口状态,您可能根本不需要坐标状态。)
    • 我仍然收到此错误:TypeError: can't access property "coordinates", jason is undefined。它 console.logs jason,但在 setViewport 之前它变得未定义。
    • @edapm:哪一行给出了这个错误?你说杰森在我们使用它之前就成功地登录到控制台了。
    • {...viewport}latitude: jason.coordinates.lat 之后的行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-12
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多