【发布时间】:2019-11-05 01:44:59
【问题描述】:
我正在开发 Reactjs 天气项目,该项目从特定的天气 api 获取数据。在加载项目时,我会通过 getCurrentPosition 函数获取我所在城市的温度信息。温度单位也可以通过拨动开关从摄氏度更改为华氏温度,反之亦然,这是我的主要目标。但是,如何在特定城市搜索中获取温度单位值?简而言之,我想在城市搜索中切换温度单位。
以下是供参考的文件 1. App.js(主文件)
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
lat: '',
lon: '',
city: '',
country: '',
humidity: '',
temperature: '',
wind: '',
description: '',
maxTemp: '',
minTemp: '',
precip: '',
pressure: '',
hourlyforecast: '',
error: '',
unit: 'C',
sunrise: '',
sunset: '',
}
}
componentDidMount = async () => {
// Tracking the location and
// Setting the state of latitude and longitude values
navigator.geolocation.getCurrentPosition(async (position) => {
this.setState({
lat: position.coords.latitude.toFixed(3),
lon: position.coords.longitude.toFixed(3)
}, () => {
if(this.state.lat && this.state.lon) {
this.fetchWeather()
} else {
this.getWeather()
}
})
},
(error) => {
toast.error(`${error.message}`,{
autoClose: 3000
})
},
{
enableHighAccuracy: true,
timeout: 50000,
maximumAge: 1000
})
}
fetchWeather = () => {
const {lat, lon} = this.state
const unitType = (this.state.unit === 'C') ? 'M' : 'I';
console.log('UNITTYPE', unitType)
// Current Weather
fetch(`${CURRENT_API}lat=${lat}&lon=${lon}&units=${unitType}&key=${API_KEY3}`)
.then(res => res.json()).then(responseJson => {
try {
console.log('DATA CURRENT', responseJson)
this.setState({
city: responseJson.data[0].city_name,
country: responseJson.data[0].country_code,
temperature: responseJson.data[0].temp,
wind: responseJson.data[0].wind_spd,
humidity: responseJson.data[0].rh,
pressure: responseJson.data[0].pres,
description: responseJson.data[0].weather.description,
isLoading: false,
}, () => {
localStorage.setItem('weather', JSON.stringify(this.state))
})
} catch {
toast.error('Error Code 429')
}
});
// Forecast Weather - Daily
fetch(`${FORECAST_API}lat=${lat}&lon=${lon}&units=${unitType}&days=6&key=${API_KEY3}`)
.then(res => res.json()).then(responseJson => {
try {
console.log('DATA I GET', responseJson)
this.setState({
forecastdays: responseJson.data,
precip: responseJson.data[0].pop,
maxTemp: responseJson.data[0].app_max_temp,
sunrise: responseJson.data[0].sunrise_ts,
sunset: responseJson.data[0].sunset_ts,
minTemp: responseJson.data[0].app_min_temp,
isLoading: false
} , () => {
localStorage.setItem('weather', JSON.stringify(this.state))
})
} catch {
toast.error('Too many requests')
}
});
// Forecast Weather - Hourly
fetch(`${HOURLY_API}lat=${lat}&lon=${lon}&units=${unitType}&key=${API_KEY3}&hours=10`)
.then(res => res.json()).then(responseJson => {
try {
this.setState({
hourlyforecast: responseJson.data,
isLoading: false
}, () => {
localStorage.setItem('weather', JSON.stringify(this.state))
})
} catch {
toast.error('Please wait some time')
}
});
}
- 输出切换开关值的函数
onUnitChange = (newUnit) => {
this.setState({
unit: newUnit
}, this.fetchWeather, this.getWeather)
}
直到上面的代码我得到输出
现在问题来了->如何将单位值传递给getWeather函数?
- 根据城市输入搜索天气信息的功能
getWeather = async (e) => {
e.preventDefault();
const city = e.target.elements.city.value;
const unitType = (this.state.unit === 'C') ? 'M' : 'I';
try {
// 1. weatherbit current data
const api_call4 = await fetch(`https://api.weatherbit.io/v2.0/current?` +
`city=${city}&units=${unitType}&key=${API_KEY3}`)
const data4 = await api_call4.json();
console.log('DATA CURRENT', data4)
// 2. weatherbit forecast data
const api_call3 = await fetch(`https://api.weatherbit.io/v2.0/forecast/daily` +
`?city=${city}&units=${unitType}&days=6&key=${API_KEY3}`)
const data3 = await api_call3.json();
console.log('DATA FORECAST', data3)
// 3. weatherbit hourly data
const api_call2 = await fetch(`https://api.weatherbit.io/v2.0/forecast/hourly` +
`?city=${city}&units=${unitType}&key=${API_KEY3}&hours=10`)
const data2 = await api_call2.json();
console.log('DATA HOURLY', data2)
if(city) {
this.setState({
temperature: data4.data[0].temp,
city: data4.data[0].city_name,
country: data4.data[0].country_code,
humidity: data4.data[0].rh,
maxTemp: data4.data[0].app_max_temp,
minTemp: data4.data[0].app_min_temp,
wind: data4.data[0].wind_spd,
description: data4.data[0].weather.description,
pressure: data4.data[0].pres,
error: "",
precip: data3.data[0].pop,
forecastdays: data3.data,
hourlyforecast: data2.data,
maxTemp: data3.data[0].app_max_temp,
minTemp: data3.data[0].app_min_temp,
sunrise: data3.data[0].sunrise_ts,
sunset: data3.data[0].sunset_ts,
isLoading: false
}, () => {
localStorage.setItem('weather2', JSON.stringify(this.state))
})
} else if(city === '') {
this.setState({
temperature: this.state.temperature,
city: this.state.city,
country: this.state.country,
humidity: this.state.humidity,
wind: this.state.wind,
description: this.state.description,
pressure: this.state.pressure,
forecastdays: this.state.forecastdays,
hourlyforecast: this.state.hourlyforecast,
precip: this.state.precip,
maxTemp: this.state.maxTemp,
minTemp: this.state.minTemp,
error: toast.error("City cannot be empty",{
autoClose: 3000
})
})
}
}
catch {
toast.error('No Data Received', {
autoClose: 3000
})
}
localStorage.getItem('weather2')
}
render() {
const {isLoading, forecastdays, hourlyforecast, precip} = this.state;
return (
<div className="container" style={{marginTop: '3.5em'}}>
<div className="row">
<div className="col-sm-4 form-container">
<Form getWeather={this.getWeather}/>
<ToastContainer transition={Bounce}
className = 'toast-background'/>
</div>
{isLoading ? <Spinner/>:
<React.Fragment>
<div className="col-sm-8 image-container">
{/* Weather Card */}
<div className="background">
<div className="container">
<div id="card" className="weather" style={sectionStyle}></div>
<div id="card" className="weather2" style={{background: ''}}>
<div className="details">
{/* Weather Details */}
<div className="content" style={{width: '125px'}}>
<Weather
temperature={this.state.temperature}
city={this.state.city}
country={this.state.country}
humidity={this.state.humidity}
description={this.state.description}
pressure={this.state.pressure}
wind={this.state.wind}
maxTemp={this.state.maxTemp}
minTemp={this.state.minTemp}
precip={precip}
tempUnit={this.state.tempUnit}
/>
</div>
{/* Forecast Cards */}
<div className="content" style={{width: '360px', marginTop: '-40px'}}>
<div style={{display: 'table', width: '300px'}}>
<SunriseSunset
style={{display: 'table-cell'}}
sunrise={this.state.sunrise}
sunset={this.state.sunset}
/>
<ConvertTempButton
style={{display: 'table-cell'}}
changeUnit={this.onUnitChange}
onUnitChange={this.onUnitChange}
unit={this.state.unit}
/>
</div>
<DailyHourly forecastdays={forecastdays} hourlyforecast={hourlyforecast}/>
</div>
{/* Forecast Cards Ends*/ }
</div>
</div>
</div>
</div>
</div>
{/* Video Background Ends */}
</div>
{/* Weather Card Ends */}
</React.Fragment>
}
</div>
</div>
);
}
export default App
我知道上面的代码不合适,但是,实现结果的正确方法是什么?非常感谢代码中的任何建议或更改。提前致谢
【问题讨论】:
-
温度单位是您使用的特定天气 API 返回的任何内容。您使用的是哪个天气 API?
-
只用
this.state.unit? -
我正在使用weatherbit api
-
Pranav 你能解决问题吗?您尝试过@MaazSyedAdeeb 的建议吗?如果问题没有解决,我会发布答案。
-
我有点困惑 this.state.unit 应该在哪里使用,根据@MaazSyedAdeeb?当我输入特定的城市,然后切换摄氏度以华氏温度时,天气信息将返回到我当前的位置
标签: javascript reactjs