Pourquoi les documents React recommandent-ils de faire AJAX dans componentDidMount, pas componentWillMount?


102

Le titre dit tout. Je comprends pourquoi componentDidMountest approprié pour tout ce qui nécessite un accès DOM, mais une requête AJAX n'en a pas nécessairement ou généralement besoin.

Ce qui donne?


@FurkanO Je pense qu'il voulait dire l'accès aux éléments DOM rendus par le composant. Et il a tout à fait raison, car si vous tentiez d'accéder auxdits éléments, componentWillMountcela échouerait étant donné que le composant ... n'a pas été monté.
ZekeDroid

@AlanH. J'ai supprimé ma question, bien sûr, vous avez accès à dom sur componentDidMount. C'est une règle, rien à expliquer à ce sujet. Merci.
FurkanO

À mon avis, c'est pourquoi nous appelons la fonction Ajax après componentDidMount, c'est que nous devons d'abord nous assurer que le rendu de l'élément est fluide au début. Après cela, nous pouvons faire un appel ajax. Si nous appelons d'abord ajax et qu'une erreur se produit, cela posera un problème lors du rendu
Faris Rayhan

Réponses:


62

componentDidMountest pour les effets secondaires. Ajout d'écouteurs d'événements, AJAX, mutation du DOM, etc.

componentWillMountest rarement utile; surtout si vous vous souciez du rendu côté serveur (l'ajout d'écouteurs d'événements provoque des erreurs et des fuites, et beaucoup d'autres choses qui peuvent mal tourner).

On parle de supprimer componentWillMountdes composants de classe car cela sert le même objectif que le constructeur. Il restera sur les createClasscomposants.


1
L'ajout d'écouteurs d'événements provoque des erreurs et des fuites tout le temps sur le serveur, ou simplement componentWillMount? Je ne vois pas vraiment la distinction.
Alan H.26

18
@Alan - Si vous utilisez React à la fois côté client et côté serveur, vous constaterez que tout ce qui se trouve à l'intérieur componentWillMountsera exécuté sur un rendu côté serveur. Wheras si vous utilisiez componentDidMountalors cela ne serait exécuté que côté client. En conséquence, mettre des éléments componentWillMountqui effectuent des interactions externes ou se lient à des événements, etc., n'est pas une bonne idée. Si vous n'avez pas l'intention de rendre vos composants côté serveur, ce n'est toujours pas une bonne idée juste pour la portabilité potentielle du code. Tout cela est en dehors de la principale raison pour laquelle c'est mauvais qui est expliqué dans la réponse de @daniula.
Mike Driver

3
componentWillMount est exécuté sur le serveur, mais componentWillUnmount (où vous supprimez les écouteurs) ne l'est pas. Cela vous obligerait à ajouter des auditeurs et à ne jamais les nettoyer.
Brigand

Les membres de l'équipe principale de React envisagent de supprimer componentWillMount des futures versions.
cchamberlain

1
@AnkitSinghaniya cela briserait le rendu du serveur et les tests unitaires superficiels.
Brigand

36

J'ai eu le même problème au début aussi. J'ai décidé d'essayer de faire des demandes, componentWillMountmais cela se termine par divers petits problèmes.

Je déclenchais le rendu lorsque l'appel ajax se termine avec de nouvelles données. À un moment donné, le rendu du composant prenait plus de temps que l'obtention de la réponse du serveur et à ce stade, le rappel ajax déclenchait le rendu sur le composant non monté. C'est une sorte de cas extrême, mais il y en a probablement plus, il est donc plus sûr de s'en tenir componentDidMount.


D'accord merci. Je pensais que cela pourrait être quelque chose comme ça, mais vous avez raison, il est surprenant que la requête ajax puisse se terminer avant le rendu.
Alan H.26

1
@daniula Êtes-vous sûr? Comment la requête AJAX peut-elle se terminer avant le rendu?
Leon Grapenthin

4
C'est le monde asynchrone du navigateur. Vous ne devez jamais supposer qu'une fonction sera toujours plus rapide que les autres. Comme je l'ai mentionné, c'est un cas extrême et signifie probablement que vous devez optimiser votre processus de rendu, mais l'utilisation d'une méthode de cycle de vie appropriée vous facilitera la vie à ce stade.
daniula

1
Le constructeur de classe @SooChengKoh ES6 est équivalent à componentWillMount, vous devez donc continuer à l'utiliser componentDidMountpour vos appels ajax.
daniula

1
@SooChengKoh - Ne doit absolument rien faire dans le constructeur qui mènera à un état qui doit être défini, qui conduira à des conditions de concurrence sur le client et le serveur. Vous ne devez jamais appeler setStateun constructeur de composant et vous n'avez aucun moyen de déterminer quand l'appel AJAX se terminera. twitter.com/dan_abramov/status/576453138598723585
cchamberlain

3

Selon la documentation, le réglage de l'état dans componentWillMountne déclenchera pas de re-rendu. Si l'appel AJAX ne bloque pas et que vous retournez un Promisequi met à jour l'état du composant en cas de succès, il y a des chances que la réponse arrive une fois que le composant a été rendu. Comme componentWillMountne déclenche pas de nouveau rendu, vous n'aurez pas le comportement attendu, à savoir le composant rendu avec les données demandées.

Si vous utilisez l'une des bibliothèques de flux et que les données demandées se retrouvent dans le magasin auquel le composant est connecté (ou héritent d'un composant connecté), ce ne sera pas un problème car la réception de ces données changera très probablement les accessoires. finalement.


1
componentWillMountne déclenche pas un nouveau rendu simplement parce qu'un nouvel état est défini avant le premier rendu. Mais s'il setStateest appelé dans un callback AJAX, il sera très certainement appelé après le premier rendu, et il déclenchera un nouveau rendu.
webdif
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.