Я пишу приложение с прогнозом погоды на React. Я получаю данные из API openweathermap.org. Но чтобы использовать это, мне нужно знать местонахождение пользователя. Поэтому я последовательно использую другие API, чтобы идентифицировать IP-адрес пользователя, местоположение, а затем данные о погоде в соответствии с этим местоположением. В каждом состоянии выборки я обновляю начальные состояния с полученной информацией. Например, когда я получаю Ip, я обновляю userIP в состояниях с помощью setState, затем, когда выбираются широта и долгота, я также обновляю userLat и userLng. Таким образом, weatherData в состояниях, который изначально является пустым массивом, обновляется последним. Проблема в том, что рендеринг запускается каждый раз при изменении одного из состояний. Поскольку один из дочерних компонентов, которому я передаю weatherData в качестве свойств, использует объект в этом извлеченном массиве weatherData, я получаю сообщение об ошибке, потому что до тех пор, пока weatherData не будет обновлена, render выполняется и передает пустой массив этому компоненту. Я попытался использовать оператор if, чтобы проверить, является ли weatherData пустым массивом, прежде чем возвращать результаты, но почему-то это не работает.
Вот мой файл App.js:
import React, {Component} from 'react';
import './App.css';
import Mainblock from './Mainblock';
import Hourly from './Hourly';
import Weekly from './Weekly';
class App extends Component {
constructor() {
super()
this.state = {
userIp: 0,
cityName: '',
cityNameNoSpace: '',
userLat: 0,
userLng: 0
}
}
componentDidMount(){
fetch("https://geoip-db.com/json/").then((data)=> {
return data.json();
}).then((ip)=>{
this.setState({userIp: ip.IPv4});
this.locateClient(this.state.userIp);
});
}
locateClient = (clientIp) => {
fetch(`https://ip-geolocation.whoisxmlapi.com/api/v1?apiKey=at_SECRETAPIKEY&ipAddress=${clientIp}`).then((data)=>{
return data.json();
}).then((locationInfo)=>{
this.setState({userLat: locationInfo.location.lat, userLng: locationInfo.location.lng, cityName: locationInfo.location.city});
let cityArray = Array.from(locationInfo.location.city);
let cityNameFiltered = '';
cityArray.forEach((letter)=>{
cityNameFiltered = cityNameFiltered + letter;
return cityNameFiltered;
})
this.setState({cityNameNoSpace: cityNameFiltered});
this.getWeatherData(this.state.cityNameNoSpace);
});
}
getWeatherData = (userCity) => {
fetch(`https://api.openweathermap.org/data/2.5/onecall?lat=${this.state.userLat}&lon=${this.state.userLng}&units=metric&appid=SECRETAPIKEY`).then((data)=>{
return data.json();
}).then((weatherInfo)=>{
this.setState({weatherData: weatherInfo});
});
}
render() {
return (
<div className="whole-container">
<div className="lside">
<Mainblock states={this.state}/>
<Weekly />
</div>
<Hourly />
</div>
);
}
}
export default App;