I am building a simple weather app where I set a place to display the weather forcast with a boolean to control if it will show or not
<div className="column">
{this.state.displayResult ? <WeatherResult /> : null}
</div>
There the displayResult
boolean will set to true by the handleSubmit()
in the form and the fetchFavWeather()
on the buttons, and will set to be false by HandleInputChange()
in the first control class
async getCoord() {
let city = {
cityname: this.state.postcodeInput
}
axios.post('http://localhost:4001/search-location', city)
.then((response) => {
console.log(response);
this.setState({
displayResult: true
});
}, (error) => {
console.log(error);
});
}
handleSubmit(e) {
e.preventDefault();
this.getCoord();
}
handleInputChange(e) {
this.setState({
postcodeInput: e.target.value,
displayResult: false
});
}
fetchFavWeather(city){
this.setState({
displayResult: false,
postcodeInput: city
},()=>{
console.log("passing fav to forcast" this.state.postcodeInput);
this.getCoord()
});
}
fetchFavCities(){
axios.get('http://localhost:4001/favouriteCites')
.then((res)=>{
this.setState({
favCts: res.data
})
});
}
render() {
this.fetchFavCities();
return (
<div>
<form onSubmit={this.handleSubmit}>
<div>
<div className="column">
{
this.state.favCts.map(
(item, index) => <button key={index} onClick = {() => {this.fetchFavWeather(item)}}>{item}</button>
)}
</div>
<div className="control">
<input className="input" type="text" placeholder="input city here" onChange={this.handleInputChange} required />
</div>
<div className="field">
<div className="control">
<input type='submit' className="button is-light is-large" value='Check Weather' />
<input type='submit' className="button is-light is-large" value='Save as Favourite' onClick = {this.saveAsFavourite}/>
</div>
</div>
</div>
</form>
<div className="column">
{this.state.displayResult ? <WeatherResult /> : null}
</div>
</div>
)
}
however in my WeatherResult Component class, I found out that the render() is being called in an infinite loop, any ideas why?
class WeatherResult extends React.Component {
constructor(props) {
super(props);
this.state = {
currentTemp: '',
humidity: '',
cityName: '',
days: []
}
}
async fetchWeather() {
let response = await fetch('http://localhost:4001/weather');
await response.json().then(data => {
console.log(data);
this.setState({
currentTemp: data['currentConditions']['temp'] '°C',
//humidity: data.main.humidity '%',
cityName: data.address,
days: data.days
})
})
}
componentDidMount() {
this.fetchWeather();
}
render() {
//console.log("why is this looping?");
return (
<div>
<p>Current Conditions at {this.state.cityName}</p>
<p>Current temperature: {this.state.currentTemp}</p>
<p>Humidity: {this.state.humidity}</p>
<p>Location: {this.state.cityName}</p>
<div>
<p>Forcast</p>
<p>Date: {this.state.days['datetime']}</p>
<p>weatherType: {this.state.days['icon']}</p>
</div>
</div>
)
}
}
export default WeatherResult;
CodePudding user response:
You are called a fetch
method inside your render
function which will cause an infinite update loop.
render() {
this.fetchFavCities();
Infinite loop will happen because you probably set these favorite cities in your state and reference them here
<div className="column">
{
this.state.favCts.map(
(item, index) => <button key={index} onClick = {() => {this.fetchFavWeather(item)}}>{item}</button>
)}
</div>
Place this outside of render
function.