React Inhalt wird zu häufig geladen

Zeppi

Aktives Mitglied
Moin, ich bin gerade dabei eine Internetseite mit der Open Weather Api zuschreiben. Dabei wird mir der Ort, Temperatur und Berschreibung angezeigt. Aber beim Laden werden die Inhalte immer häufiger als 1 Mal gerendert. Dazu habe ich im Internet auch etwas gefunden, und zwar React.memo, das hat aber nicht funktioniert. Ein weiteres Problem ist, dass die Inhalte bei den ersten Anfragen immer 'undefined' sind und nur bei der letzten Anfrage kommt dann das gewollte Ergebnis (Sehe ich nur, wenn ich mir mal den Inhalt mit Console.log() ausgeben lasse). Aber dadurch, dass es nur beim letzten Aufruf klappt, kann ich den Namen des divs nicht ändern, weil jedes Mal sagt er mir, dass er den IndexOf nicht lesen kann. <div className={description.indexOf('rain') > 0 ? 'rainy' : description.indexOf('cloud') > 0 ? 'cloudy' : 'clear')}>
Vielleicht hat jemand ja eine Idee, damit es nicht immer re-rendered wird.

[CODE lang="javascript" title="Wetter"]const Wetter = () => {
const [temp, setTemp] = useState();
const [city, setCity] = useState();
const [desc, setDesc] = useState();

window.onload = function () {
weatherBallon();
}
const weatherBallon = () => {
fetch('https://api.openweathermap.org/data/2.5/weather?q=Hamburg&appid=')
.then(resp => resp.json())
.then(data => drawWeather(data))
.catch(function (error) {
console.log(error)
});
}

function drawWeather(d) {
setTemp(Math.round(parseFloat(d.main.temp)-273.15))
setCity(d.name)
var description = d.weather[0].description
setDesc(description)
}




return (
<div>
<Anzeige temp={temp} city={city} desc={desc}></Anzeige>
</div>

)
};

export default Wetter;[/CODE]
[CODE lang="javascript" title="Anzeige"]const Anzeige = React.memo(props => {
var description = props.desc;
return (
<div>
<div className={description.indexOf('rain') > 0 ? 'rainy' : description.indexOf('cloud') > 0 ? 'cloudy' : 'clear')}>
<h1>{props.temp}</h1>
<h2>{props.city}</h2>
</div>
)
});
export default Anzeige;[/CODE]
 
Erstmal: window.onload in react-code sieht sehr merkwürdig aus, das gehört da eher nicht hin. Um die Daten initial zu laden, solltest du eher useEffect nutzen.



Das, ins Blaue geraten, viermalige rendern von Anzeige liegt an der Funktionsweise von useState, in asynchronem Code führt jedes set* zu einem neuem Rendern.
In deinem Fall also:
1. Rendern beim initialen Anzeigen, das Triggert dann das fetchen der Daten, und führt zu:
2. Rendern, wenn setTemp aufgerufen wird
3. Rendern, wenn setCity aufgerufen wird
4. Rendern, wenn setDesc aufgerufen wird

React.memo hilft dabei nicht, da dies nur dafür sorgt, das die Komponente auch wirklich nur dann neu gerendert wird, wenn sich dir Pros ändern. In deine Fall ändern sie sich ja, deshalb wird da jedes Mal neu gerendert.

Lösen kannst du das, in dem du nicht drei States, sondern einen einzelnen nutzt. Grob etwa:
Javascript:
setWetherData({
  temp: ..., 
  city: ...,
  desc: ...,
});

Damit hast du nur einen State, der sich ändern, und der alle zusammengehörenden Daten enthält.
 
Erstmal: window.onload in react-code sieht sehr merkwürdig aus, das gehört da eher nicht hin. Um die Daten initial zu laden, solltest du eher useEffect nutzen.



Das, ins Blaue geraten, viermalige rendern von Anzeige liegt an der Funktionsweise von useState, in asynchronem Code führt jedes set* zu einem neuem Rendern.
In deinem Fall also:
1. Rendern beim initialen Anzeigen, das Triggert dann das fetchen der Daten, und führt zu:
2. Rendern, wenn setTemp aufgerufen wird
3. Rendern, wenn setCity aufgerufen wird
4. Rendern, wenn setDesc aufgerufen wird

React.memo hilft dabei nicht, da dies nur dafür sorgt, das die Komponente auch wirklich nur dann neu gerendert wird, wenn sich dir Pros ändern. In deine Fall ändern sie sich ja, deshalb wird da jedes Mal neu gerendert.

Lösen kannst du das, in dem du nicht drei States, sondern einen einzelnen nutzt. Grob etwa:
Javascript:
setWetherData({
  temp: ...,
  city: ...,
  desc: ...,
});

Damit hast du nur einen State, der sich ändern, und der alle zusammengehörenden Daten enthält.
Danke, das hat mir geholfen. Habe es leider erst jetzt gesehen. UseEffect kannte ich noch nicht, das werde ich mir gleich mal angucken.
 

Zurück
Oben