Warum empfehlen die React-Dokumente, AJAX in componentDidMount und nicht in componentWillMount auszuführen?

102

Der Titel sagt alles. Ich verstehe, warum dies componentDidMountfür alles geeignet ist, was DOM-Zugriff erfordert, aber eine AJAX-Anfrage benötigt dies nicht unbedingt oder normalerweise.

Was gibt?

Alan H.
quelle
@FurkanO Ich denke, er meinte den Zugriff auf DOM-Elemente, die von der Komponente gerendert wurden. Und er hat vollkommen recht, denn wenn Sie versuchen würden, auf diese Elemente zuzugreifen, componentWillMountwürde dies fehlschlagen, da die Komponente ... nicht gemountet wurde.
ZekeDroid
@ AlanH. Meine Frage gelöscht, natürlich haben Sie Zugriff auf dom auf componentDidMount. Dies ist eine Regel, nichts zu erklären. Vielen Dank.
FurkanO
Meiner Meinung nach ist der Grund, warum wir die Ajax-Funktion aufrufen, nachdem componentDidMount ist, dass wir zuerst sicherstellen müssen, dass das Element am Anfang reibungslos gerendert wird. Danach können wir einen Ajax-Anruf tätigen. Wenn wir zuerst
Ajax

Antworten:

62

componentDidMountist für Nebenwirkungen. Hinzufügen von Ereignis-Listenern, AJAX, Mutieren des DOM usw.

componentWillMountist selten nützlich; Besonders wenn Sie sich für das serverseitige Rendern interessieren (das Hinzufügen von Ereignis-Listenern führt zu Fehlern und Lecks sowie zu vielen anderen Dingen, die schief gehen können).

Es wird über das Entfernen componentWillMountvon Klassenkomponenten gesprochen, da dies demselben Zweck dient wie der Konstruktor. Es bleibt auf createClassKomponenten.

Räuber
quelle
1
Das Hinzufügen von Ereignis-Listenern verursacht Fehler und leckt ständig auf dem Server oder nur in componentWillMount? Ich sehe den Unterschied nicht wirklich.
Alan H.
18
@Alan - Wenn Sie React sowohl auf der Clientseite als auch auf der Serverseite verwenden, werden Sie feststellen, dass alles, was sich darin componentWillMountbefindet, auf einem serverseitigen Render ausgeführt wird. Wenn Sie dagegen verwenden componentDidMount, wird dies nur auf der Clientseite ausgeführt. Daher componentWillMountist es keine gute Idee , Dinge einzubringen , die externe Interaktionen ausführen oder an Ereignisse usw. binden. Wenn Sie nicht vorhaben, Ihre Komponenten auf dem Server zu rendern, ist dies immer noch keine gute Idee, nur um eine mögliche Code-Portabilität zu gewährleisten. Dies ist alles außerhalb des Hauptgrundes, warum es schlecht ist, was in @daniulas Antwort erklärt wird.
Mike Driver
3
componentWillMount wird auf dem Server ausgeführt, componentWillUnmount (wo Sie Listener entfernen) jedoch nicht. Dies würde dazu führen, dass Sie Listener hinzufügen und diese niemals bereinigen.
Brigand
Die Mitarbeiter des React-Kernteams erwägen, componentWillMount aus zukünftigen Versionen zu entfernen.
Cchamberlain
1
@AnkitSinghaniya würde das Server-Rendering und flache Unit-Tests unterbrechen.
Brigand
36

Ich hatte das gleiche Problem auch am Anfang. Ich habe mich entschlossen, Anfragen zu stellen, componentWillMountaber es kommt zu verschiedenen kleinen Problemen.

Ich habe das Rendern ausgelöst, als der Ajax-Aufruf mit neuen Daten beendet wurde. Irgendwann dauerte das Rendern der Komponente länger als das Abrufen einer Antwort vom Server, und zu diesem Zeitpunkt löste der Ajax-Rückruf das Rendern einer nicht gemounteten Komponente aus. Dies ist eine Art Randfall, aber es gibt wahrscheinlich noch mehr, daher ist es sicherer, sich daran zu halten componentDidMount.

daniula
quelle
Okay danke. Ich dachte, es könnte so etwas sein, aber Sie haben Recht, es ist überraschend, dass die Ajax-Anforderung vor dem Rendern beendet werden könnte.
Alan H.
1
@daniula Bist du sicher? Wie kann die AJAX-Anforderung vor dem Rendern beendet werden?
Leon Grapenthin
4
Dies ist eine asynchrone Browser-Welt. Sie sollten niemals davon ausgehen, dass eine Funktion immer schneller ist als die andere. Wie ich bereits erwähnt habe, ist dies ein Randfall und bedeutet wahrscheinlich, dass Sie Ihren Renderprozess optimieren sollten, aber die Verwendung der richtigen Lebenszyklusmethode wird Ihr Leben an diesem Punkt viel einfacher machen.
Daniula
1
Der @SooChengKoh ES6-Klassenkonstruktor entspricht componentWillMount, daher sollten Sie ihn weiterhin componentDidMountfür Ihre Ajax-Aufrufe verwenden.
Daniula
1
@SooChengKoh - Sollte auf keinen Fall im Konstruktor etwas tun, was zu einem Status führt, der festgelegt werden muss, was zu Race-Bedingungen auf Client und Server führt. Sie sollten niemals setStateeinen Komponentenkonstruktor aufrufen und können nicht bestimmen, wann der AJAX-Aufruf abgeschlossen wird. twitter.com/dan_abramov/status/576453138598723585
cchamberlain
3

Laut Dokumentationseinstellung componentWillMountlöst der Status in kein erneutes Rendern aus. Wenn der AJAX-Aufruf nicht blockiert wird und Sie einen zurückgeben Promise, der den Status der Komponente bei Erfolg aktualisiert, besteht die Möglichkeit, dass die Antwort eintrifft, sobald die Komponente gerendert wurde. Da componentWillMountkein erneutes Rendern ausgelöst wird, haben Sie nicht das erwartete Verhalten, dh die Komponente, die mit den angeforderten Daten gerendert wird.

Wenn Sie eine der Flussbibliotheken verwenden und die angeforderten Daten in dem Speicher landen, mit dem die Komponente verbunden ist (oder von einer verbundenen Komponente erbt), ist dies kein Problem, da der Empfang dieser Daten höchstwahrscheinlich die Requisiten ändert schließlich.

gabriel.g
quelle
1
componentWillMountlöst kein erneutes Rendern aus, nur weil vor dem ersten Rendern ein neuer Status definiert wurde. Wenn setStatees jedoch in einem AJAX-Rückruf aufgerufen wird, wird es definitiv nach dem ersten Rendern aufgerufen und löst ein erneutes Rendern aus.
Webdif