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

基于React JS的天气API应用开发问题:无法获取API数据

Fixing Your React Weather API App Issues

Let's break down why your app isn't fetching data and fix each problem one by one:

Key Issues in Your Current Code

  • You never trigger the API fetch: Your fetchApi function is defined but never called—typing in the input only updates the search state, but doesn't send the request to the weather API.
  • No error handling for invalid cities: When the API can't find a city, it returns a 404 response with an error message, but your code tries to access resJson.main anyway, which will cause errors.
  • Initial state confusion: The city state starts as null, so your app immediately shows "No Data Found" before the user even searches for a city.
  • Invalid React syntax: You're using class instead of className for your cloud elements—React requires className for CSS classes.

Fixed Component Code

import React, { useState } from "react";

const TempApp = () => {
  const [cityData, setCityData] = useState(null); // Renamed for clarity
  const [search, setSearch] = useState("");
  const [error, setError] = useState(""); // Track errors for invalid cities

  const fetchApi = async () => {
    if (!search.trim()) {
      setError("Please enter a city name");
      setCityData(null);
      return;
    }

    try {
      const url = `https://api.openweathermap.org/data/2.5/weather?q=${search}&units=metric&appid=4ebb9418ca605fa1931880e565ec065c`;
      const response = await fetch(url);
      
      if (!response.ok) {
        throw new Error("未找到城市");
      }

      const resJson = await response.json();
      setCityData(resJson.main);
      setError(""); // Clear error on successful fetch
    } catch (err) {
      setError(err.message);
      setCityData(null); // Reset data when there's an error
    }
  };

  // Handle enter key press in input
  const handleKeyPress = (e) => {
    if (e.key === "Enter") {
      fetchApi();
    }
  };

  return (
    <div className="box">
      <div className="InputData">
        <input
          type="search"
          className="InputField"
          value={search}
          onChange={(event) => setSearch(event.target.value)}
          onKeyPress={handleKeyPress}
          placeholder="请输入城市名称..."
        />
        <button onClick={fetchApi} className="search-btn">查询天气</button>

        {/* Initial state: prompt user to search */}
        {!cityData && !error && (
          <div>
            <h3><b>输入城市名称获取天气数据</b></h3>
            <div id="clouds">
              <div className="cloud x1"></div>
              <div className="cloud x2"></div>
              <div className="cloud x3"></div>
              <div className="cloud x4"></div>
              <div className="cloud x5"></div>
            </div>
          </div>
        )}

        {/* Error state: show city not found or other errors */}
        {error && (
          <div>
            <h3><b>{error}</b></h3>
            <div id="clouds">
              <div className="cloud x1"></div>
              <div className="cloud x2"></div>
              <div className="cloud x3"></div>
              <div className="cloud x4"></div>
              <div className="cloud x5"></div>
            </div>
          </div>
        )}

        {/* Success state: show weather data */}
        {cityData && !error && (
          <div>
            <div className="info">
              <h2 className="location">
                <i className="fas fa-street-view"></i> {search}
              </h2>
              <h1 className="temp"> {cityData.temp} °C </h1>
              <h3 className="tempmin_max">
                {cityData.temp_min} °C | {cityData.temp_max} °C
              </h3>
            </div>
            <div className="wave-one"></div>
            <div className="wave-two"></div>
            <div className="wave-three"></div>
            <div id="clouds">
              <div className="cloud x1"></div>
              <div className="cloud x2"></div>
              <div className="cloud x3"></div>
              <div className="cloud x4"></div>
              <div className="cloud x5"></div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

export default TempApp;

What Changed & Why

  1. Added fetch triggers: Added a search button and an onKeyPress handler to trigger fetchApi when the user presses Enter, so the API request actually runs when the user submits a city name.
  2. Error handling:
    • Added an error state to track and display user-friendly messages (like empty input or "未找到城市").
    • Used try/catch blocks to handle network errors and API 404 responses.
    • Checked response.ok to detect failed API requests before parsing the JSON.
  3. State improvements:
    • Renamed city to cityData for better clarity (since it holds the weather data object, not just the city name).
    • Split UI states into initial (prompt user), error, and success flows to match your requirements.
  4. Fixed React syntax: Changed all class attributes to className for cloud elements to comply with React's rules.
  5. Better UX:
    • Added a placeholder to the input field to guide users.
    • Added a °C symbol to temperature values for clearer display.
    • Fixed spacing in the min/max temperature line.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 13:22:32