You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Hook中async/await Promise未捕获拒绝问题及地址获取报错修复

解决跨文件async/await调用API时的Promise拒绝与字段未定义错误

你的错误主要来自三个核心问题,下面逐一说明并给出修正方案:

核心问题分析

  1. Axios响应结构错误:你直接访问response.address,但Axios的GET请求返回的响应对象中,API实际返回的数据存放在response.data字段里,直接取response.address会得到undefined,进而触发字段访问报错。
  2. API返回字段缺失风险:Nominatim API返回的address对象中,部分字段(如house_number、town)并非始终存在,直接拼接会引发类型错误。
  3. 未处理异常与依赖缺失:async函数没有错误捕获逻辑,API调用失败会导致未处理的Promise拒绝;同时useEffect依赖数组为空,props.coords更新时无法重新触发请求。

修正后的代码

queries-hook.js

import axios from "axios";

export const getAddressFromLongLat = async (coords) => {
  const URL = "http://nominatim.openstreetmap.org/reverse";
  try {
    const response = await axios.get(URL, {
      params: {
        format: "json",
        lat: coords.lat,
        lon: coords.long
      },
      // GET请求无需设置Content-Type,改用Accept指定接收格式
      headers: {
        "Accept": "application/json; charset=UTF-8"
      }
    });
    // 提取API返回的实际数据
    const data = response.data;
    if (!data.address) {
      throw new Error("未获取到有效地址信息");
    }
    // 用默认值处理可能缺失的字段,避免报错
    return {
      street: `${data.address.road || ""} ${data.address.house_number || ""}`.trim(),
      cp: data.address.postcode || "",
      city: data.address.town || data.address.city || "",
      country: (data.address.country_code || "").toUpperCase()
    };
  } catch (error) {
    console.error("地址获取失败:", error);
    // 抛出错误让调用组件处理
    throw error;
  }
};

React组件代码

import { getAddressFromLongLat } from "../hooks/queries-hook";
import React, { useEffect, useState } from "react";

const Component = (props) => {
  const [address, setAddress] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchFromLongLat = async () => {
      if (!props.coords) return;
      try {
        const addressData = await getAddressFromLongLat(props.coords);
        console.log("nominatim返回数据:", addressData);
        setAddress(addressData);
        setError(null);
      } catch (err) {
        setError("获取地址失败,请稍后重试");
        setAddress(null);
      }
    };
    fetchFromLongLat();
    // 将props.coords加入依赖,确保经纬度变化时重新请求
  }, [props.coords]);

  if (error) return <div>{error}</div>;
  if (!address) return <div>加载中...</div>;

  return (
    <div>
      <p>街道:{address.street}</p>
      <p>邮编:{address.cp}</p>
      <p>城市:{address.city}</p>
      <p>国家:{address.country}</p>
    </div>
  );
};

export default Component;

关键优化点

  • Axios响应处理:必须通过response.data获取API返回的JSON数据,这是Axios的标准响应结构。
  • 字段容错:用||为可选字段设置默认值,也可使用ES6可选链?.(如data.address?.road)进一步避免报错。
  • 错误捕获:在async函数中加入try/catch,处理API调用失败、数据格式异常等情况,避免未处理的Promise拒绝。
  • useEffect依赖:将props.coords加入依赖数组,确保传入的经纬度更新时,组件自动重新发起请求。

内容的提问来源于stack exchange,提问作者BenoHiT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 15:30:41