React天气应用无效输入致页面渲染中断的解决方案咨询
React天气应用无效输入问题解决方案
我开发了一个包含两个组件的React天气应用:用户输入正确城市名时,系统通过API获取数据并渲染;但输入错误城市名或搜索栏为空时,点击提交或按回车触发onSubmit后,页面会停止渲染变成空白。希望实现:输入无效内容时,渲染默认天气数据,或停止无效输入的API请求。
App.js 组件
import React, { useState } from "react"; import "./App.css"; import Maindata from "./Components/Maindata"; import Search from "./Components/Search"; function App() { const [location, setLocation] = useState(); return ( <div className="mainpage"> <div className="searchComp"> <Search {...{ location, setLocation }} /> </div> <div className="details"> <Maindata city={location} /> </div> </div> ); } export default App;
Search.js 组件
import React, { useState } from "react"; import "../Componentstyle/search.css"; export default function Search({ setLocation }) { const [city, setCity] = useState(""); const handlesubmit = (e) => { e.preventDefault(); setLocation(city); }; return ( <div className="main"> <nav className="istclass"> <form className="form" onSubmit={handlesubmit}> <div className="search"> <input value={city} placeholder="search city" className="searchbox" onChange={(e) => setCity(e.target.value)} /> <button className="nd" type="button" onClick={handlesubmit}> Submit </button> </div> </form> </nav> </div> ); }
Maindata.js 组件
import React, { useState, useEffect } from "react"; import "../Componentstyle/Main.css"; export default function Maindata({ city = "mansehra" }) { const [data, setData] = useState(); const weather = async (city) => { const key = "1ab6ef20384db1d7d9d205d609f7eef0"; await fetch( `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${key}&units=metric&formatted=0` ) .then((response) => response.json()) .then((actualData) => setData(actualData)); }; useEffect(() => { weather(city); }, [city]); if (!data) { return <div>Loading...</div>; } const link = `http://openweathermap.org/img/w/${data.weather[0].icon}.png`; return ( <> <div className="maindata"> <div className="city">{data.name}</div> <div className="temp">{data.main.temp.toFixed()} C</div> <div className="icon"> <img src={link} alt="not found" />{" "} </div> <div className="feel">feels Like {data.main.feels_like.toFixed()} C</div> <div className="wind">Wind {data.wind.speed} Km/hr</div> <div className="cloudy">{data.weather[0].main}</div> <div className="humidity">humidity {data.main.humidity}%</div> <div className="sunrise"> sunrise :- {new Date(data.sys.sunrise * 1000).toUTCString()}{" "} </div> <div className="sunset"> sunset :- {new Date(data.sys.sunset * 1000).toUTCString()} </div> </div> </> ); }
解决方案
1. 前端输入校验(Search组件)
在提交前过滤空输入,只有有效内容才更新城市状态,否则加载默认数据:
const handlesubmit = (e) => { e.preventDefault(); const trimmedCity = city.trim(); // 仅当输入非空时更新城市,否则设置默认城市 setLocation(trimmedCity || "mansehra"); };
2. API错误处理(Maindata组件)
捕获API返回的错误,避免无效数据覆盖现有内容:
const weather = async (city) => { const key = "1ab6ef20384db1d7d9d205d609f7eef0"; try { const response = await fetch( `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${key}&units=metric&formatted=0` ); const actualData = await response.json(); // 城市不存在时加载默认数据 if (actualData.cod === "404") { weather("mansehra"); return; } setData(actualData); } catch (error) { console.error("请求失败:", error); // 请求出错时回退到默认数据 weather("mansehra"); } };
3. 优化请求触发条件(Maindata组件)
避免city为空或undefined时发起无效请求:
useEffect(() => { if (city) { weather(city); } else { // 初始状态或空值时加载默认数据 weather("mansehra"); } }, [city]);
4. 渲染容错处理(Maindata组件)
渲染前检查数据完整性,防止因字段缺失导致页面崩溃:
if (!data) { return <div>Loading...</div>; } // 校验核心字段是否存在 if (!data.name || !data.main || !data.weather?.length) { return <div>无法获取天气数据,显示默认内容...</div>; } const link = `http://openweathermap.org/img/w/${data.weather[0].icon}.png`; // 后续渲染代码保持不变
5. App组件初始化默认值
给location设置初始默认城市,避免初始渲染时的undefined状态:
const [location, setLocation] = useState("mansehra");
最终效果
- 输入为空时,自动加载默认城市数据
- 输入错误城市名时,API返回错误后自动回退到默认数据
- 页面始终保持有效内容渲染,不会因无效输入变为空白
内容的提问来源于stack exchange,提问作者Ahsan Khalid
相关产品推荐
相关产品推荐

