首页 > 解决方案 > 从 Promise 返回一个特定的字符串

问题描述

我正在编写一个 React/Next.js 应用程序,我正在使用 what3words 将项目映射到一个位置。我的代码接收三词地址,将其转换为坐标,然后应该在 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 地图。

标签: javascriptreactjstypescriptasync-awaitnext.js

解决方案


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>
);

推荐阅读