react.js 中 Openweather api 调用失败
2021-02-03
394
我想通过开放天气 API 获取天气数据。我注意到控制台中的数据没有下载,即使与 API 的连接也正确建立。通过在浏览器中输入 API 地址,将显示数据。单击获取天气按钮后,不会下载任何数据。我在代码中遇到了一个有问题的代码片段。是什么导致了此代码中的问题?
e.preventDefault();
const city = e.target.elements.city.value;
const country = e.target.elements.country.value;
上述这段代码在通过 API 获取数据时会导致问题。如果我删除它,数据将通过 API 下载,不会出现任何问题,并且我会获得伦敦的当前天气。
整个 App.js
import React from "react";
import './App.css';
import 'weather-icons/css/weather-icons.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import Weather from "./components/weather.component";
import Form from "./components/form.component";
const API_KEY = "79b5009058dfaeaae8ed70533cb72a0d";
class App extends React.Component {
constructor() {
super();
this.state = {
city: undefined,
country: undefined,
icon: undefined,
main: undefined,
celsius: undefined,
temp_max: undefined,
temp_min: undefined,
description: '"',
error: false
};
this.weatherIcon = {
Thunderstorm: "wi-thunderstorm",
Drizzle: "wi-sleet",
Rain: "wi-storm-showers",
Snow: "wi-snow",
Atmosphere: "wi-fog",
Clear: "wi-day-sunny",
Clouds: "wi-day-fog"
};
}
calCelsius(temp) {
let cell = Math.floor(temp - 273.15);
return cell;
}
get_WeatherIcon(icons, rangeId){
switch(true){
case rangeId >= 200 && rangeId <= 232:
this.setState({icon: this.weatherIcon.Thunderstorm})
break;
case rangeId >= 300 && rangeId <= 321:
this.setState({icon: this.weatherIcon.Drizzle})
break;
case rangeId >= 500 && rangeId <= 531:
this.setState({icon: this.weatherIcon.Rain})
break;
case rangeId >= 600 && rangeId <= 622:
this.setState({icon: this.weatherIcon.Snow})
break;
case rangeId >= 701 && rangeId <= 781:
this.setState({icon: this.weatherIcon.Snow})
break;
case rangeId === 800:
this.setState({icon: this.weatherIcon.Clear})
break;
case rangeId >= 801 && rangeId <= 804:
this.setState({icon: this.weatherIcon.Clouds})
break;
default:
this.setState({icon: this.weatherIcon.Clouds})
}
}
getWeather = async(e)=>{
e.preventDefault();
const city = e.target.elements.city.value;
const country = e.target.elements.country.value;
if(city && country) {
const api_call = await fetch(`http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=${API_KEY}`);
const response = await api_call.json();
console.log(response);
this.setState({
city: response.name,
country: response.country,
celsius: this.calCelsius(response.main.temp),
temp_max: this.calCelsius(response.main.temp_max),
temp_min: this.calCelsius(response.main.temp_min),
description: response.weather[0].description,
});
this.get_WeatherIcon(this.weatherIcon, response.weather[0].id);
} else {
this.setState({error: true});
}
};
render() {
return (
<div className="App">
<Form loadweather={this.getWeather} error={this.state.error}/>
<Weather
city={this.state.city}
country={this.state.country}
temp_celsius={this.state.celsius}
temp_max={this.state.temp_max}
temp_min={this.state.temp_min}
description={this.state.description}
weatherIcon={this.state.icon}
/>
</div>
)
}
}
export default App;
form.component.jsx
import React from "react";
import "./form.style.css";
const Form = props => {
return(
<div className="container">
<div>{props.error ? error() : null}</div>
<form action="">
<div className="container">
<div className="row">
<div className="col-md-3 offset-md-2">
<input
type="text"
className="form-control"
name="city"
autoComplete="off"
placeholder="City"
/>
</div>
<div className="col-md-3">
<input
type="text"
className="form-control"
name="country"
autoComplete="off"
placeholder="Country"
/>
</div>
<div className="col-md-3 mt-md-0 text-md-left">
<button onSubmit={props.loadweather} className="btn btn-warning">Get Weather</button>
</div>
</div>
</div>
</form>
</div>
);
}
function error() {
return(
<div className="alert alert-danger mx-5" role="alert">
Please Enter City and Country
</div>
)
}
export default Form;
weather.component.jsx
import React from 'react';
const Weather = (props) => {
return(
<div className="container">
<div className="cards pt-4">
<h1>{props.city}</h1>
<h5 className="py-4">
<i className={`wi ${props.weatherIcon} display-1`} />
</h5>
{props.temp_celcius ? (<h1 className="py-2"></h1>): null}
<h1 className="py-2">{props.temp_celsius}°</h1>
{minmaxTemp(props.temp_min, props.temp_max)}
<h4 className="py-3">{props.description}</h4>
</div>
</div>
);
};
function minmaxTemp(min,max) {
if(min && max) {
return(
<div>
<span className="px-4">{min}°</span>
<span className="px-4">{max}°</span>
</div>
);
}
}
export default Weather;
1个回答
问题似乎出在 form.component.jsx
尝试使用
<input className="btn btn-warning" type="submit" value="Get Weather" />
而不是
<button onSubmit={props.loadweather} className="btn btn-warning">Get Weather</button>
另外,使用
<form onSubmit={props.loadweather}>
以防万一,请参考此内容: https://reactjs.org/docs/forms.html
祝您编码愉快!
Akshay
2021-02-04