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

React回调内用useEffect报错,如何实现城市天气数据获取?

解决React中事件回调内调用API的状态更新问题

错误原因

你在onCreate回调里用useEffect触发请求报错,是因为React Hooks必须在组件顶层作用域调用,不能嵌套在事件回调、循环、条件判断这类代码块里,这是React的Hook规则,违反就会触发报错。

正确解法

核心思路是:把用户输入的city存为状态变量,用useEffect监听这个状态的变化,当city更新时自动执行API请求,既符合Hook规则,又能正确处理异步请求的状态更新。

完整代码示例

import { useState, useEffect } from 'react';
import Create from './Create';

function WeatherApp() {
  // 存储天气数据
  const [target, setTarget] = useState(null);
  // 存储用户输入的城市
  const [city, setCity] = useState('');
  // 加载状态,优化用户体验
  const [loading, setLoading] = useState(false);
  // 错误状态,捕获请求异常
  const [error, setError] = useState(null);

  // 监听city状态变化,触发API请求
  useEffect(() => {
    // 如果城市为空,直接返回不执行请求
    if (!city.trim()) return;

    const fetchWeatherData = async () => {
      setLoading(true);
      setError(null);
      try {
        const res = await fetch(`https://goweather.herokuapp.com/weather/${city}`);
        if (!res.ok) throw new Error('天气数据请求失败');
        const weatherData = await res.json();
        setTarget(weatherData);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchWeatherData();
  }, [city]); // 仅当city变化时,重新执行这个effect

  // 接收Create组件传来的城市
  const handleCitySubmit = (inputCity) => {
    setCity(inputCity);
  };

  return (
    <div>
      <Create onCreate={handleCitySubmit} />
      
      {/* 根据状态渲染不同内容 */}
      {loading && <p>正在获取天气数据...</p>}
      {error && <p>出错了:{error}</p>}
      {target && (
        <div className="weather-info">
          <h2>{city}的天气</h2>
          <p>温度:{target.temperature}</p>
          <p>天气:{target.description}</p>
          <p>风力:{target.wind}</p>
        </div>
      )}
    </div>
  );
}

export default WeatherApp;

关键说明

  1. 状态分离:把用户输入的city和天气数据target拆成两个独立状态,onCreate回调只负责更新city,逻辑更清晰。
  2. 合规使用useEffect:在组件顶层定义useEffect,依赖city状态,当用户输入新城市时,自动触发请求,完全符合Hook规则。
  3. 异步处理:用async/await处理fetch请求,同时加入loading和error状态,避免直接读取undefined的target,还能给用户反馈。
  4. 条件渲染:通过{target && ...}的方式,确保只有当target有数据时才渲染天气信息,不会出现undefined相关的渲染错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:28:31