You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React组件间传值方案:搜索输入传递至天气数据组件

React组件间传值实现天气搜索功能解决方案

我有两个React组件:Search组件提供搜索输入框供用户输入城市名称;Maindata组件负责调用天气API并展示气温、风速等天气数据。需要实现将用户在Search组件中输入的城市名称传递至Maindata组件的API调用逻辑,从而渲染对应城市的天气数据。

核心解决方案:使用React的状态提升机制,将共享状态(选中的城市)提升到两个组件的共同父组件App.js中,通过props实现组件间的数据传递和回调。


1. 修改App.js(父组件)

将城市状态提升到App组件,同时给子组件传递必要的props:

import "./App.css";
import Maindata from "./Components/Maindata";
import Search from "./Components/Search";
import { useState } from "react";

function App() {
  // 保存用户选择的城市名称
  const [selectedCity, setSelectedCity] = useState("mansehra");

  // 接收Search组件传递的城市名称
  const handleCitySubmit = (city) => {
    setSelectedCity(city);
  };

  return (
    <div className="mainpage">
      <div className="searchComp">
        {/* 给Search组件传递回调函数,用于接收输入的城市 */}
        <Search onSubmit={handleCitySubmit} />
      </div>
      <div className="details">
        {/* 给Maindata组件传递选中的城市 */}
        <Maindata city={selectedCity} />
      </div>
    </div>
  );
}

export default App;

2. 修改Search组件(子组件)

移除不必要的逻辑,通过props接收父组件的回调函数,提交时将输入的城市传递给父组件:

import React, { useState } from "react";
import "../Componentstyle/search.css";

export default function Search({ onSubmit }) {
  const [location, setLocation] = useState("");
  
  const handleSubmit = () => {
    // 确保输入不为空时再触发回调
    if (location.trim()) {
      onSubmit(location.trim());
    }
  };

  return (
    <div className="main">
      <nav className="istclass">
        <form className="form" onSubmit={(e) => e.preventDefault()}>
          <div className="search">
            <input
              value={location}
              placeholder="search city"
              className="searchbox"
              onChange={(e) => setLocation(e.target.value)}
            />
            <button className="nd" type="button" onClick={handleSubmit}>
              Submit
            </button>
          </div>
        </form>
      </nav>
    </div>
  );
}

修复了原代码中handlesubmit函数的错误(原代码中event.target.value获取的是按钮的值,而非输入框内容),改为直接使用组件内部的location状态值。


3. 修改Maindata组件(子组件)

通过props接收城市名称,将城市作为useEffect的依赖项,实现城市变化时自动调用API更新数据:

import React, { useState, useEffect } from "react";
import "../Componentstyle/Main.css";

export default function Maindata({ city }) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  const fetchWeather = async () => {
    if (!city) return;
    
    setLoading(true);
    setError(null);
    const key = "XYZ"; // 替换为你的实际API密钥
    
    try {
      const response = await fetch(
        `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${key}&units=metric&formatted=0`
      );
      
      if (!response.ok) {
        throw new Error("城市未找到或API请求失败");
      }
      
      const actualData = await response.json();
      setData(actualData);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchWeather();
  }, [city]); // 当city变化时重新调用API

  if (loading) {
    return <div>Loading...</div>;
  }

  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>
  );
}

优化说明:

  • 添加了加载状态和错误状态的处理,提升用户体验
  • 将原有的async/await和.then()混合写法统一为async/await,代码更清晰
  • 优化了日期显示格式为本地时间,更符合用户习惯
  • 增加了API请求失败的错误处理,避免页面崩溃

内容的提问来源于stack exchange,提问作者Ahsan Khalid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 00:35:26