React调用Weatherbit API报错TypeError: weather is undefined
报错根因
weather is undefined是渲染阶段访问了不存在的对象属性导致的,具体触发点有4个:
- 接口数据取值层级错误:Weatherbit v2.0/current接口的返回结构为
{ data: [实际天气对象], ...元信息 },当前代码直接把整个接口响应体存入state,传给子组件的data是外层响应对象,本身不存在weather、temp等天气字段,解构后自然是undefined。 - 异步渲染空值问题:接口请求是异步执行的,组件首次挂载时如果
data没有设置初始有效值,直接对undefined做解构会直接抛错。 - 接口请求参数错误:URL中API密钥拼接错误,模板字符串未正确解析变量还多拼接了冗余字符
1,会直接触发接口鉴权失败,返回错误对象而非有效天气数据。 - 属性访问无兜底:直接访问
weather.description时,只要weather为undefined就会抛类型错误,没有做容错处理。
修复方案
1. 修正接口请求逻辑
调整useEffect中的数据取值、参数拼接,补全依赖项:
useEffect(() => { if(!town) return; // 修正API密钥拼接,替换为实际的密钥变量,删除多余的尾缀1 const url = `https://api.weatherbit.io/v2.0/current?lat=${town.latitud}&lon=${town.longitud}&key=${APIKEY}&include=minutely`; api.get(url).then((res)=>{ // 先判断返回结构有效性,取data数组的第一项作为有效天气数据存入state if(!res.err && res?.data?.length){ setData(res.data[0]); } }) }, [town]) // 补全依赖数组,避免闭包问题
如果你的api实例是基于axios封装且已经配置了自动返回res.data的响应拦截器,就把取值逻辑对应调整为setData(res.data[0])即可,以控制台打印的实际返回结构为准。
2. 给子组件加空值兜底
修改CityWeather组件,增加加载态判断、字段默认值、可选链容错:
import React from "react"; const CityWeather = ({data, cityName}) => { // 数据未返回时展示加载态,避免解构空值报错 if (!data) return <div className="cityWeather">天气数据加载中...</div> // 给解构字段加默认值,避免单字段缺失导致报错 const { weather = {}, app_temp, wind_spd, temp } = data return ( <div className="cityWeather"> <div className="cityWeatherPrincipalData"> <h2 id="city">{cityName}</h2> <h4 id="cityWeatherTemperatureNow">当前温度:{temp}℃</h4> <div id="cityWeatherTemperatureMaxMin"> <h4>体感温度:{app_temp}℃</h4> </div> <div id="cityWeatherWind"> <h4>风速:{wind_spd}m/s</h4> </div> {/* 用可选链+兜底值访问嵌套属性,避免weather为空时报错 */} <h2 id="cityWeatherStateSky">{weather?.description || '天气状态获取失败'}</h2> </div> </div> ) } export default CityWeather
校验要点
- 接口请求成功后先在控制台打印存入state的数值,确认其本身存在
weather对象,且weather.description有有效值,排除经纬度传错、密钥过期、接口跨域等问题导致的返回异常。 - 父组件中
data的state初始值建议设为null,不要留undefined,配合子组件的加载态判断即可覆盖首次渲染的空值场景。
内容的提问来源于stack exchange,提问作者Luciano795
相关产品推荐
相关产品推荐

