React天气API组件条件渲染问题:输入无效值时报空白及TypeError错误
问题修复方案
核心问题分析
- 条件渲染逻辑完全颠倒:原代码中
city ? 显示无数据 : 显示天气的逻辑完全反了,应该是有有效数据时显示天气,否则显示无数据提示。 - 未处理API错误响应:当请求无效地点时,API返回的是含错误信息的对象(而非null),此时
city有值但缺少main等关键字段,直接访问会触发类型错误。 - 初始状态无空值保护:组件挂载初期
city为null,直接访问city.main.temp会报错。
修复后的代码
import React from "react"; const Weather = () => { const [city, setCity] = React.useState(null); const [search, setSearch] = React.useState(""); const [place, setPlace] = React.useState("New York"); React.useEffect(() => { const api = async () => { try { const url = `https://api.openweathermap.org/data/2.5/weather?q=${place}&units=metric&appid=f61848ab5fa06141797d0d033e36ad85`; const response = await fetch(url); const data = await response.json(); // 仅当API返回有效天气数据时更新city,否则设为null if (data.main) { setCity(data); } else { setCity(null); } } catch (err) { console.error("API请求失败:", err); setCity(null); } }; api(); }, [place]); const handleSubmit = (e) => { e.preventDefault(); if (search.trim()) { // 避免空白值请求 setPlace(search); setSearch(""); } }; return ( <div> <form onSubmit={handleSubmit}> <input type="search" value={search} onChange={(e) => setSearch(e.target.value)} placeholder="输入城市名称" /> <button type="submit">搜索</button> </form> {/* 修正条件渲染逻辑:有有效数据时显示天气,否则提示无数据 */} {city ? ( <div> <h1>气温 {city.main.temp}°C</h1> <p>地点 {city.name}</p> {/* 使用可选链操作符保护weather数组访问 */} <img src={`http://openweathermap.org/img/wn/${city.weather?.[0]?.icon}@2x.png`} alt="天气图标" /> </div> ) : ( <p>No Data Found</p> )} </div> ); }; export default Weather;
关键修改点说明
- 修正条件渲染逻辑:将
city ? 无数据 : 天气改为city ? 天气 : 无数据,符合正常业务逻辑。 - API响应校验:判断返回数据是否包含
main字段(有效天气数据的核心标志),无效则将city设为null,确保无数据提示正确触发。 - 空白值拦截:提交表单时检查
search是否为空白,避免无意义的API请求。 - 空值保护:使用可选链操作符
?.访问city.weather?.[0]?.icon,即使weather字段不存在也不会抛出类型错误。 - 统一表单提交逻辑:将点击按钮和回车提交合并到
handleSubmit,简化代码同时符合表单规范。
内容的提问来源于stack exchange,提问作者Rahul Dhiman
相关产品推荐
相关产品推荐

