Ich versuche, mit Async/Await in einer React.js-App eine einfache Get-Anfrage an meinen Server zu stellen. Der Server lädt ein einfaches JSON unter /data was so aussieht
JSON
{
id: 1,
name: "Aditya"
}
Ich kann die Daten mit der einfachen jquery ajax get-Methode an meine React-App übertragen. Ich möchte jedoch die Axios-Bibliothek und Async/Await verwenden, um den ES7-Standards zu folgen. Mein aktueller Code sieht so aus:
Mit diesem Ansatz erhalte ich den folgenden Fehler:
Objekte sind als React-Kind nicht gültig (gefunden: [object Promise]). Wenn Sie eine Sammlung von untergeordneten Elementen rendern wollten, verwenden Sie stattdessen ein Array.
Implementiere ich es nicht richtig?
render() funktioniert einwandfrei, da ich deutlich erwähnt habe, dass ich Details erhalten kann, wenn ich $.ajax() verwende. Welchen zusätzlichen Code soll ich hinzufügen? Dies ist eine einfache Get-Anforderung an den Server unter Verwendung von ES7-Standards.
– Singh
13. Oktober 2017 um 15:38 Uhr
Aktualisieren Sie Ihre Frage im Idealfall mit a lauffähig minimal reproduzierbares Beispiel, das das Problem mit einem Platzhalter für das Ajax demonstriert (z. B. setTimeout oder ähnliches), mit Stack Snippets (the [<>] Symbolleistenschaltfläche). Stack Snippets unterstützen React, einschließlich JSX; Hier ist, wie man es macht.
– TJ Crowder
13. Oktober 2017 um 15:43 Uhr
…aber der hinzugefügte Code macht die Dinge absolut klar. 🙂
– TJ Crowder
13. Oktober 2017 um 15:48 Uhr
Zu Ihrer Information, async/await ist Teil von ES2017, nicht ES7 (ES2016).
– Felix Klinge
13. Oktober 2017 um 17:20 Uhr
Danke für die Information.
– Singh
13. Oktober 2017 um 17:24 Uhr
TJ Crowder
Zwei Probleme springen heraus:
Dein getData gibt nie etwas zurück, also sein Versprechen (async Funktionen geben immer ein Promise zurück) erfüllt werden undefined wenn es nicht ablehnt
Die Fehlermeldung zeigt deutlich, dass Sie versuchen, das Versprechen direkt zu machen getData zurückgibt, anstatt darauf zu warten, dass es sich begleicht, und dann den Erfüllungswert zu erbringen
Adressierung #1: getData sollte Rückkehr das Ergebnis des Anrufs json:
Weiteres Update: Sie haben eine Präferenz für die Verwendung angegeben await in componentDidMount statt then und catch. Sie würden das tun, indem Sie ein verschachteln async IIFE-Funktion darin und stellt sicher, dass die Funktion nicht werfen kann. (componentDidMount selbst kann nicht sein asyncnichts wird dieses Versprechen verbrauchen.) Bsp.:
Es gab mir diesen Fehler “‘this’ ist vor super() nicht erlaubt”. Also habe ich super(); direkt vor “this.state = {data: null};” was später zu einem neuen Fehler führte: “‘getData’ is not defined no-undef”
– Singh
13. Oktober 2017 um 15:54 Uhr
@Morfsys: Ich glaube nicht, dass das die genaue Fehlermeldung ist. 🙂 Ich sagte “etwas wie this”. Ich habe das oben aktualisiert, fehlte this. an getData.
– TJ Crowder
13. Oktober 2017 um 15:57 Uhr
.catch(err => { /*…den Fehler behandeln…*/}); wird jetzt ausgeführt. Es besagt, dass res.json() keine Funktion ist.
– Singh
13. Oktober 2017 um 16:16 Uhr
Nur zur Info… return res.json() müsste sein return await res.json() im obigen Beispiel, richtig? Wenn Sie es in der nächsten Zeile zurückgeben, wird die Rückgabezeile sofort ausgeführt, anstatt darauf zu warten, von definiert zu werden const res genau darüber.
– dave4jr
9. Mai 2018 um 22:13 Uhr
@dave4jr: Nein, das musst du nicht — aber es könnte aus Sicht der Code-Wartung eine gute Idee sein, danke. “Wenn Sie es in der nächsten Zeile zurückgeben, wird die Rückgabezeile sofort ausgeführt, anstatt zu warten …” Nein, das ist falsch. Das return Zeile wird nicht ausgeführt, bis die await axios('/data') beschließt. Also der Code ohne die await würde funktionieren, das Versprechen erstellt von getData Sein async würde nur demjenigen versklaven, der zurückgekehrt ist res.json(). Aber von einer Code-Wartung. pers., du hast recht, besser zu await es — weil es leicht wäre, es durcheinander zu bringen, wenn man Änderungen daran vornimmt getData.
– TJ Crowder
10. Mai 2018 um 5:59 Uhr
Singh
Nach meiner Erfahrung in den letzten Monaten habe ich erkannt, dass der beste Weg, dies zu erreichen, folgender ist:
Wenn Sie versuchen, bei Ereignissen wie Klick eine Post-Anfrage zu stellen, dann rufen Sie an getData() Funktion für das Ereignis und ersetzen Sie den Inhalt wie folgt:
Wenn Sie eine Anfrage stellen, wenn die Komponente gerade geladen wird, ersetzen Sie sie einfach async getData() mit async componentDidMount() und ändern Sie die Renderfunktion wie folgt:
Dies ist im Grunde nur meine Antwort, umformuliert. Außerdem: 1. Nicht machen componentWillMount ein async Funktion. React ignoriert das zurückgegebene Promise. 2. Es sei denn res.data ein Accessor ist, der ein Versprechen zurückgibt, macht es keinen Sinn, ihn zu verwenden await beim Zugriff darauf.
– TJ Crowder
18. Dezember 2017 um 8:13 Uhr
Ich habe lediglich versucht, die Antwort zu vereinfachen. Nichts für ungut, aber ich denke then und catch ist nicht der neueste Standard (ES6) für das Nachfassen mit einem Versprechen. Außerdem funktionierte res.json() bei mir nicht und ich musste es durch res.data ersetzen, das mit einem Versprechen einhergehtGET oder POST Anfrage.
– Singh
18. Dezember 2017 um 8:34 Uhr
then und catchsind die ES2015 (alias “ES6”) Art, mit Versprechen umzugehen. async/await sind die ES2017 (“ES8”) Weg. Aber Sie können nur verwenden await innerhalb eines async Funktion und Herstellung componentWillMountasync schafft ein Versprechen, das niemals eingelöst wird. Wenn Sie verwenden möchten await stattdessen ist das in Ordnung, aber Sie würden das anders machen als nur zu schlagen async an componentWillMount. Ehrlich gesagt ist es auf jeden Fall nicht cool, zwei Monate später wiederzukommen und eine Antwort zu posten, die nur die vorhandene ohne Zuschreibung optimiert.
render() funktioniert einwandfrei, da ich deutlich erwähnt habe, dass ich Details erhalten kann, wenn ich $.ajax() verwende. Welchen zusätzlichen Code soll ich hinzufügen? Dies ist eine einfache Get-Anforderung an den Server unter Verwendung von ES7-Standards.
– Singh
13. Oktober 2017 um 15:38 Uhr
Aktualisieren Sie Ihre Frage im Idealfall mit a lauffähig minimal reproduzierbares Beispiel, das das Problem mit einem Platzhalter für das Ajax demonstriert (z. B.
setTimeout
oder ähnliches), mit Stack Snippets (the[<>]
Symbolleistenschaltfläche). Stack Snippets unterstützen React, einschließlich JSX; Hier ist, wie man es macht.– TJ Crowder
13. Oktober 2017 um 15:43 Uhr
…aber der hinzugefügte Code macht die Dinge absolut klar. 🙂
– TJ Crowder
13. Oktober 2017 um 15:48 Uhr
Zu Ihrer Information,
async/await
ist Teil von ES2017, nicht ES7 (ES2016).– Felix Klinge
13. Oktober 2017 um 17:20 Uhr
Danke für die Information.
– Singh
13. Oktober 2017 um 17:24 Uhr