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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 00:55:16