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
相关产品推荐
相关产品推荐

