React组件传值后city未定义致页面空白问题求助
问题解决方案
核心问题分析
- Search组件中
Maindata组件未被正确渲染(仅写了JSX但未放入return的DOM结构中) - 按钮点击事件逻辑错误,且未阻止表单默认提交行为
Maindata中错误地将console.log的返回值(undefined)赋值给city变量- useEffect未监听
props.city变化,无法触发新的API请求 - 初始状态未设置合理默认值,导致首次请求时city为undefined
修正步骤及代码
1. 修正Search组件
- 将
Maindata组件放入return的JSX结构中 - 修复表单提交逻辑,阻止页面默认刷新
- 给useState设置初始空字符串默认值
import React, { useState } from "react"; import Maindata from "./Maindata"; import "../Componentstyle/search.css"; export default function Search() { const [location, setLocation] = useState(""); // 处理表单提交,阻止默认刷新行为 const handleSubmit = (e) => { e.preventDefault(); // 可选:添加输入非空验证 if (!location.trim()) return; }; return ( <div className="main"> <nav className="istclass"> <form className="form" onSubmit={handleSubmit}> <div className="search"> <input value={location} placeholder="search city" className="searchbox" onChange={(e) => setLocation(e.target.value)} /> <button className="nd" type="submit"> Submit </button> </div> </form> </nav> {/* 将Maindata放入渲染结构,传递location作为city参数 */} <Maindata city={location} /> </div> ); }
2. 修正Maindata组件
- 直接使用
props.city,去掉错误的console.log赋值 - 给useEffect添加
props.city依赖,城市变化时自动重新请求API - 增加API请求错误处理,避免数据异常导致页面崩溃
- 仅当
props.city不为空时才发起请求
import React, { useState, useEffect } from "react"; import "../Componentstyle/Main.css"; export default function Maindata(props) { const [data, setData] = useState(null); const [error, setError] = useState(null); const fetchWeather = async () => { // 城市为空时不发起请求 if (!props.city.trim()) { setData(null); setError(null); return; } const key = "1ab6ef20384db1d7d9d205d609f7eef0"; try { const response = await fetch( `https://api.openweathermap.org/data/2.5/weather?q=${props.city}&appid=${key}&units=metric&formatted=0` ); if (!response.ok) throw new Error("城市未找到或请求失败"); const actualData = await response.json(); setData(actualData); setError(null); } catch (err) { setError(err.message); setData(null); } }; // 监听props.city变化,自动触发新请求 useEffect(() => { fetchWeather(); }, [props.city]); // 错误状态展示 if (error) return <div>错误:{error}</div>; // 未输入城市或加载中状态 if (!data) return <div>请输入城市名称...</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} °C</div> <div className="icon"> <img src={link} alt={data.weather[0].description} />{" "} </div> <div className="feel">体感温度 {data.main.feels_like} °C</div> <div className="wind">风速 {data.wind.speed} Km/hr</div> <div className="cloudy">{data.weather[0].main}</div> <div className="humidity">湿度 {data.main.humidity}%</div> <div className="sunrise"> 日出时间:{new Date(data.sys.sunrise * 1000).toLocaleString()} </div> <div className="sunset"> 日落时间:{new Date(data.sys.sunset * 1000).toLocaleString()} </div> </div> ); }
关键说明
- 组件渲染规则:React组件必须包含在return的JSX结构中才会被渲染,之前的
Maindata仅写在函数体中未生效,导致页面空白。 - 表单行为控制:submit类型按钮点击会触发页面刷新,必须用
e.preventDefault()阻止默认行为。 - API请求优化:监听props变化确保城市更新时自动重新请求,增加错误处理避免页面崩溃,同时过滤空输入无效请求。
- 初始状态设置:给
location设置空字符串默认值,避免首次渲染时传递undefined给API参数。
内容的提问来源于stack exchange,提问作者Ahsan Khalid
相关产品推荐
相关产品推荐

