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

React天气应用摄氏度转华氏度切换功能开发问题求助

React天气应用温度转换功能修复方案

现存问题

  • 状态职责混淆:fahr字段初始为布尔值,调用API后被覆盖为华氏度数值,同时承担了「显示开关」和「温度数值存储」两个冲突的职责
  • 转换逻辑失效:handleConvert 函数仅固定将fahr设为true,没有实现切换显示的功能
  • 无条件渲染逻辑:温度展示区域没有做显示判断,两种单位默认同时展示
  • 事件函数定义错误:handleSubmit 被嵌套定义在handleChange中,每次输入都会重新生成函数实例,存在性能隐患

修复代码

import React, { Component } from "react";
import Greeting from "./Greeting";

const API_key = "dsdfghjkjhgfd";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      city: "",
      country: undefined,
      weather: "",
      temp: "",
      // 拆分状态:fahr专门存华氏度数值,新增showFahrenheit做显示开关
      fahr: "",
      showFahrenheit: false
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleConvert = this.handleConvert.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.newTemp = this.newTemp.bind(this);
  }

  newTemp(temp) {
    let cell = Math.floor((temp * 9) / 5) + 32;
    return cell;
  }

  calCelsius(temp) {
    let cell = Math.floor(temp);
    return cell;
  }

  handleConvert() {
    // 切换显示开关状态
    this.setState(prevState => ({
      showFahrenheit: !prevState.showFahrenheit
    }));
  }

  handleChange(event) {
    const { name, value } = event.target;
    this.setState({ [name]: value });
  }

  // handleSubmit提到外层定义
  async handleSubmit(e) {
    e.preventDefault();
    const city = this.state.city;
    fetch(
      `http://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${API_key}`
    )
      .then((response) => response.json())
      .then((response) => {
        console.log(response);
        this.setState({
          city: `${response.name}`,
          country: `${response.sys.country}`,
          temp: this.calCelsius(response.main.temp),
          fahr: this.newTemp(response.main.temp),
          weather: `${response.weather[0].main}`,
          // 每次查询新城市后默认隐藏华氏度,需要时再点击按钮显示
          showFahrenheit: false
        });
      });
  }

  render() {
    let date = String(new window.Date());
    date = date.slice(0, 15);

    return (
      <div
        className={
          typeof this.state.weather != "undefined"
            ? this.state.temp > 16
              ? "app hot"
              : "app"
            : "app"
        }
      >
        <main>
          <div className="search-box">
            <form onSubmit={this.handleSubmit}>
              <input
                type="text"
                className="search-bar"
                placeholder="Enter a city"
                name="city"
                onChange={this.handleChange}
                value={this.state.city}
              />
            </form>
          </div>

          <div>
            <div className="location-box">
              <div className="location">
                {this.state.city},{this.state.country}
              </div>
              <div className="date">{date}</div>
              <div className="greet">
                <Greeting />
              </div>
              <div className="weather-box">
                <div className="temp">{this.state.temp}°C</div>
                {/* 加条件渲染,只有showFahrenheit为true时才显示华氏度 */}
                {this.state.showFahrenheit && <div className="fahr">{this.state.fahr}°F</div>}
                <div className="weather">{this.state.weather}</div>
                <button onClick={this.handleConvert}>Convert Temp</button>
              </div>
            </div>
          </div>
        </main>
      </div>
    );
  }
}

export default App;

实现效果

  • 初始状态及查询新城市后,默认仅显示摄氏度温度
  • 点击「Convert Temp」按钮即可切换华氏度的显示/隐藏状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 04:24:05