Perché i documenti di React consigliano di eseguire AJAX in componentDidMount, non in componentWillMount?


102

Il titolo dice tutto. Capisco perché componentDidMountè appropriato per tutto ciò che richiede l'accesso DOM, ma una richiesta AJAX non necessariamente o di solito ne ha bisogno.

Cosa succede?


@ FurkanO Penso che intendesse l'accesso agli elementi DOM resi dal componente. E ha perfettamente ragione perché se si tentasse di accedere a detti elementi in componentWillMountesso fallirebbe dato che il componente ... non è stato montato.
ZekeDroid

@AlanH. Eliminata la mia domanda, ovviamente hai accesso a dom su componentDidMount. Questa è una regola, niente da spiegare al riguardo. Grazie.
FurkanO

A mio parere è questo il motivo per cui chiamiamo la funzione Ajax dopo componentDidMount è che dobbiamo assicurarci prima che l'elemento venga renderizzato senza problemi all'inizio. Dopodiché possiamo fare una chiamata ajax. Se chiamiamo prima ajax e si verifica un errore, causerà problemi con il rendering
Faris Rayhan

Risposte:


62

componentDidMountè per gli effetti collaterali. Aggiunta di listener di eventi, AJAX, modifica del DOM, ecc.

componentWillMountè raramente utile; soprattutto se ti interessa il rendering lato server (l'aggiunta di listener di eventi causa errori e fughe di notizie e molte altre cose che possono andare storte).

Si parla di rimuovere componentWillMountdai componenti di classe poiché ha lo stesso scopo del costruttore. Rimarrà sui createClasscomponenti.


1
L'aggiunta di listener di eventi causa errori e perdite per tutto il tempo sul server, o semplicemente in componentWillMount? Non vedo davvero la differenza.
Alan H.

18
@Alan - Se stai usando React sia sul lato client che sul lato server, scoprirai che qualsiasi cosa all'interno componentWillMountverrà eseguita su un rendering lato server. Dov'è che se lo stessi usando, componentDidMountverrebbe eseguito solo sul lato client. Di conseguenza, inserire cose componentWillMountche eseguono interazioni esterne o si legano a eventi, ecc., Non è una grande idea. Se non si prevede di eseguire il rendering dei componenti sul lato server, non è ancora una buona idea solo per la potenziale portabilità del codice. Questo è tutto al di fuori del motivo principale per cui è brutto, spiegato nella risposta di @daniula.
Mike Driver

3
componentWillMount viene eseguito sul server, ma componentWillUnmount (dove rimuovi i listener) non lo è. Ciò ti farebbe aggiungere ascoltatori e non pulirli mai.
Brigante

Le persone del team principale di React stanno prendendo in considerazione la rimozione di componentWillMount dalle versioni future.
cchamberlain

1
@AnkitSinghaniya interromperà il rendering del server e gli unit test superficiali.
Brigante

36

Ho avuto lo stesso problema anche all'inizio. Ho deciso di provare a fare richieste incomponentWillMount ma si finisce in vari piccoli problemi.

Stavo attivando il rendering quando la chiamata ajax termina con nuovi dati. Ad un certo punto il rendering del componente ha richiesto più tempo che ottenere una risposta dal server ea questo punto il callback ajax ha attivato il rendering sul componente non montato. Questo è un caso limite ma probabilmente ce n'è di più, quindi è più sicuro attenersi componentDidMount.


Va bene, grazie. Ho pensato che potrebbe essere qualcosa del genere, ma hai ragione, è sorprendente che la richiesta ajax possa finire prima del rendering.
Alan H.

1
@daniula Sei sicuro? Come può terminare la richiesta AJAX prima del rendering?
Leon Grapenthin

4
Questo è il mondo asincrono del browser. Non dovresti mai presumere che una funzione sarà sempre più veloce delle altre. Come ho già detto, è un caso limite e probabilmente significa che dovresti ottimizzare il tuo processo di rendering, ma l'uso del metodo del ciclo di vita appropriato ti renderà la vita molto più semplice a questo punto.
daniula

1
Il costruttore della classe @SooChengKoh ES6 è equivalente a componentWillMount, quindi dovresti continuare a usarlo componentDidMountper le tue chiamate ajax.
daniula

1
@SooChengKoh - Sicuramente non dovrebbe fare nulla nel costruttore che porterà a uno stato che deve essere impostato, che porterà a condizioni di competizione su client e server. Non dovresti mai chiamare setStateun costruttore di componenti e non hai modo di determinare quando la chiamata AJAX verrà completata. twitter.com/dan_abramov/status/576453138598723585
cchamberlain

3

Secondo la documentazione, l'impostazione dello stato in componentWillMountnon attiverà un nuovo rendering. Se la chiamata AJAX non si blocca e si restituisce un Promiseaggiornamento che aggiorna lo stato del componente in caso di successo, ci sono possibilità che la risposta arrivi una volta che il componente è stato renderizzato. ComecomponentWillMount non innesca un nuovo rendering, non avrai il comportamento che ti aspettavi, ovvero il componente che viene visualizzato con i dati richiesti.

Se usi una qualsiasi delle librerie di flusso e i dati richiesti finiscono nel negozio a cui è connesso il componente (o ereditano da un componente connesso) questo non sarà un problema poiché la ricezione di quei dati, molto probabilmente, cambierà le props infine.


1
componentWillMountnon attiva un nuovo rendering solo perché un nuovo stato è definito prima del primo rendering. Ma se setStateviene chiamato in un callback AJAX, sarà sicuramente chiamato dopo il primo rendering e attiverà un nuovo rendering.
webdif
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.