React调用OpenWeatherMap API时出现Cannot read properties of undefined (reading '0')错误
React调用OpenWeatherMap API时出现Cannot read properties of undefined (reading '0')错误
嗨,我完全懂你遇到的这个头疼问题!这个错误的核心原因很明确:当API请求还没返回数据,或者返回的结果里根本没有weather字段时,你直接尝试访问cityData.weather[0],但此时cityData.weather是undefined,自然没法读取它的第0个元素。下面给你几个实用的解决思路,一步步帮你搞定:
1. 给初始状态设置更合理的默认值
你现在把cityData的初始值设成了空对象{},这就导致组件第一次渲染时,cityData.weather必然是undefined。可以把初始状态改成null,或者直接给weather字段一个空数组兜底:
// 方案一:初始设为null,后续判断是否存在 const [cityData, setCityData] = useState(null); // 方案二:直接给weather默认空数组 const [cityData, setCityData] = useState({ weather: [] });
2. 在JSX里添加严谨的条件判断
即使有可选链操作符?.,最好还是结合空值合并或者条件渲染来兜底,避免出现无效的图片链接。比如:
<img src={cityData?.weather?.[0]?.icon ? `https://openweathermap.org/img/wn/${cityData.weather[0].icon}@2x.png` : sun} alt="天气图标" />
或者用逻辑与操作符先确认weather存在且有内容,再渲染图片:
{cityData?.weather && cityData.weather.length > 0 && ( <img src={`https://openweathermap.org/img/wn/${cityData.weather[0].icon}@2x.png`} alt="天气图标" /> )}
3. 处理API请求的错误情况
有时候如果输入的城市名不正确,OpenWeatherMap的API会返回错误信息(比如cod: "404"),这时候返回的data里根本没有weather字段。你可以在请求逻辑里判断请求是否成功,失败时设置默认数据或者提示错误:
useEffect(function(){ async function fetchData(){ try { const res = await fetch(cityWeatherData); const data = await res.json(); // 判断API是否返回成功数据 if (data.cod === 200) { setCityData(data); } else { // 失败时设置默认数据,避免weather字段缺失 setCityData({ weather: [] }); console.error('获取天气数据失败:', data.message); } } catch (err) { console.error('请求出错:', err); setCityData({ weather: [] }); } } fetchData(); }, [props.city]); // 记得把props.city加入依赖数组,城市变化时重新请求
4. 添加加载状态(可选但推荐)
在API请求过程中,你可以显示一个加载提示,避免用户看到空白或者异常内容:
const [cityData, setCityData] = useState(null); const [isLoading, setIsLoading] = useState(true); useEffect(function(){ async function fetchData(){ setIsLoading(true); try { const res = await fetch(cityWeatherData); const data = await res.json(); if (data.cod === 200) { setCityData(data); } else { setCityData({ weather: [] }); console.error('获取天气数据失败:', data.message); } } catch (err) { console.error('请求出错:', err); setCityData({ weather: [] }); } finally { setIsLoading(false); } } fetchData(); }, [props.city]); // 渲染时先判断加载状态 if (isLoading) { return <div>正在加载天气数据...</div>; } return ( // 你的组件内容 );
这样调整后,就能彻底避免那个烦人的undefined错误啦!
备注:内容来源于stack exchange,提问作者pierogi01
相关产品推荐
相关产品推荐

