Das Programm laden
Auch das Laden von Daten ist ein Job für einen Effekt. Die App soll den Server einmal nach dem Programm fragen, wenn sie erscheint, der Effekt hat also die Abhängigkeiten []. Die Bands stehen in der Datei bands.json, und du lädst sie mit fetch(), wie im JavaScript-Kurs:
useEffect(() => {
async function bandsLaden() {
const antwort = await fetch("bands.json");
setBands(await antwort.json());
}
bandsLaden();
}, []);Warum die Funktion darin? fetch() braucht await, und await funktioniert nur in einer async-Funktion. Aber die Funktion, die du useEffect gibst, kann selbst nicht async sein: Eine async-Funktion gibt immer ein Promise zurück, und React erwartet von einem Effekt nichts oder ein Cleanup. Also legt der Effekt eine async-Funktion an und ruft sie sofort auf.
Der erste Render zeigt eine leere Liste, weil bands mit [] beginnt. Einen Moment später kommen die Daten an, setBands() ändert den State, und React rendert die Liste mit den Bands. Der Effekt läuft nicht noch einmal: Seine Abhängigkeiten haben sich nicht geändert.
Während der Nutzer wartet, sollte die Seite das sagen, und wenn der Server mit einem Fehler antwortet, sollte sie auch das sagen. Beides ist nur mehr State: laedt, das true ist, bis die Antwort kommt, und fehler mit dem Text einer Fehlermeldung oder "", wenn es keine gibt. Die Seite zeigt beides mit &&:
{laedt && <p>Lädt…</p>}
{fehler !== "" && <p className="fehler">{fehler}</p>}Und denke an antwort.ok aus dem JavaScript-Kurs: Es ist false, wenn der Server mit einem Fehler geantwortet hat, etwa 404 Not Found bei einem falsch geschriebenen Dateinamen.
Ein typischer Fehler ist, fetch() direkt in der Komponente aufzurufen, ohne Effekt. Dann lädt jeder Render die Daten neu, die Daten ändern den State, der neue State rendert neu … und die App fragt den Server immer wieder, ohne Ende.
So schreibst du es:
Anweisungen
- 1
Füge einen Effekt mit den Abhängigkeiten
[]hinzu, derbands.jsonlädt und die Bands mitsetBands()inbandssetzt. Dann zeigt die Liste alle fünf Bands. - 2
Füge eine State-Variable
laedthinzu, am Anfangtrue, und setze sie nachsetBands()auffalse. Solange sietrueist, zeige<p>Lädt…</p>über der Liste. - 3
Wenn die Antwort nicht OK ist, setze
laedtauffalse, schreibeDas Programm konnte nicht geladen werden.in eine State-Variablefehler(am Anfang"") und beende die Funktion mitreturn. Zeige den Fehler in<p className="fehler">über der Liste. Probiere es aus: Schreibe den Dateinamen infetch()falsch und korrigiere ihn dann wieder.