React天气数据无法显示,出现TypeError: Cannot read properties of undefined (reading 'temp')
React天气应用报错"TypeError: Cannot read properties of undefined (reading 'temp')"解决方法
问题
开发React天气应用时无法展示完整天气数据,控制台抛出错误:TypeError: Cannot read properties of undefined (reading 'temp')。仅当使用setCity(resjson.main)时能正常显示气温,但存储完整API响应(setCity(resjson))就会报错,需要同时展示天气状况、气温及气温极值。
错误原因
- API URL拼写错误:原URL缺少关键参数分隔符,
weatherq=${search}nits=metric应为weather?q=${search}&units=metric,导致API返回错误响应(如城市不存在提示),此时resjson中无main字段,访问city.main.temp自然报错。 - 未处理请求失败/错误响应:搜索空字符串或API请求失败时,返回的响应结构不符合预期,直接存入state会导致渲染报错。
- 条件渲染判断不严谨:仅判断
city是否存在,但未检查city.main和city.weather是否有效。
修复步骤
1. 修正API URL
补全URL中缺失的参数分隔符,确保请求格式正确:
const url = `http://api.openweathermap.org/data/2.5/weather?q=${search}&units=metric&APPID=83ea3057047027c6c4521d32d69250a0`;
2. 添加错误处理逻辑
过滤空字符串请求,仅在API返回成功响应时更新state:
const fetchApi = async () => { if (!search.trim()) return; // 空字符串不发送请求 try { const url = `http://api.openweathermap.org/data/2.5/weather?q=${search}&units=metric&APPID=83ea3057047027c6c4521d32d69250a0`; const res = await fetch(url); const resjson = await res.json(); if (resjson.cod === 200) { // 仅存储成功响应 setCity(resjson); } else { setCity(null); // 错误响应时重置state } } catch (err) { console.error('API请求失败:', err); setCity(null); } };
3. 优化条件渲染
确保所需字段存在后再渲染,避免访问undefined属性:
{city && city.main && city.weather?.length > 0 ? ( <div className="info"> <h1 className="temp">{city.main.temp} °Cel</h1> <h1 className="weather">{city.weather[0].main}</h1> <h3 className="tempmin_max"> Min : {city.main.temp_min} °Cel | Max : {city.main.temp_max} °Cel </h3> </div> ) : ( <p>请输入有效城市名称</p> )}
完整修复代码
import React, { useEffect, useState } from "react"; import "./css/style.css"; import { BiStreetView } from "react-icons/bi"; const Tempapp = () => { const [city, setCity] = useState(null); const [search, setSearch] = useState(""); useEffect(() => { const fetchApi = async () => { if (!search.trim()) return; try { const url = `http://api.openweathermap.org/data/2.5/weather?q=${search}&units=metric&APPID=83ea3057047027c6c4521d32d69250a0`; const res = await fetch(url); const resjson = await res.json(); if (resjson.cod === 200) { setCity(resjson); } else { setCity(null); } } catch (error) { console.error('获取天气数据失败:', error); setCity(null); } }; fetchApi(); }, [search]); return ( <> <div className="box"> <div className="inputData"> <input type="search" className="inputField" value={search} placeholder="Enter city" onChange={(event) => setSearch(event.target.value)} /> </div> {city && city.main && city.weather?.length > 0 ? ( <div className="info"> <h1 className="temp">{city.main.temp} °Cel</h1> <h1 className="weather">{city.weather[0].main}</h1> <h3 className="tempmin_max"> Min : {city.main.temp_min} °Cel | Max : {city.main.temp_max} °Cel </h3> </div> ) : ( <p>请输入有效城市名称</p> )} </div> </> ); }; export default Tempapp;
说明
- 修正URL后,API返回完整的天气数据,
setCity(resjson)可正常存储所有字段。 - 空字符串过滤和错误处理避免了无效请求和异常数据导致的渲染问题。
- 严谨的条件渲染确保只有当所需数据全部存在时才展示,彻底解决"Cannot read properties of undefined"错误。
内容的提问来源于stack exchange,提问作者Mustafa Mulla
相关产品推荐
相关产品推荐

