React Hook中async/await Promise未捕获拒绝问题及地址获取报错修复
解决跨文件async/await调用API时的Promise拒绝与字段未定义错误
你的错误主要来自三个核心问题,下面逐一说明并给出修正方案:
核心问题分析
- Axios响应结构错误:你直接访问
response.address,但Axios的GET请求返回的响应对象中,API实际返回的数据存放在response.data字段里,直接取response.address会得到undefined,进而触发字段访问报错。 - API返回字段缺失风险:Nominatim API返回的
address对象中,部分字段(如house_number、town)并非始终存在,直接拼接会引发类型错误。 - 未处理异常与依赖缺失: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
相关产品推荐
相关产品推荐

