Si vous commencez à apprendre React ou avez déjà utilisé cette bibliothèque pendant un certain temps, vous avez sûrement rencontré des erreurs ou des avertissements liés aux fonctions asynchrones, notamment en utilisant le hook useEffect
.
Lorsque j'apprenais la fonctionnalité de ce crochet, je ne comprenais pas la raison d'utiliser le retour dans cette fonction puisque dans la plupart des cas, il n'est pas nécessaire de l'utiliser, et React fonctionne parfaitement bien sans lui.
Au fur et à mesure que je me familiarisais avec le fonctionnement de React et le cycle de vie des composants, j'ai commencé à remarquer que dans de nombreux cas, il est trop important d'utiliser le retour dans le hook useEffect
, en particulier dans les effets secondaires.
Un effet secondaire peut être la récupération de données à partir d'un serveur distant, la lecture ou l'écriture sur le stockage local, la configuration d'écouteurs d'événements ou la configuration d'un abonnement. Ces effets secondaires peuvent se produire lorsqu'un bouton est cliqué, qu'un formulaire est soumis ou lorsqu'un composant est monté et démonté.
Le crochet useEffect
de React permet aux composants fonctionnels de faire des choses lorsqu'un composant est monté ou lorsque certaines propriétés ou certains états changent. Ce crochet permet également de nettoyer lorsque le composant est démonté.
La gestion des effets secondaires dans React est une tâche de complexité moyenne. Cependant, de temps en temps, vous pouvez rencontrer des difficultés à l'intersection du cycle de vie des composants (rendu initial, assemblage, utilisation, désassemblage) et du cycle de vie des effets secondaires (démarré, en cours, terminé).
L'une de ces difficultés survient lorsqu'un effet secondaire se termine et tente de mettre à jour l'état d'un composant déjà désassemblé.
Cela provoque un avertissement React comme celui-ci :
Les fuites de mémoire dans les applications React résultent principalement de la non-annulation des abonnements effectués lorsqu'un composant a été monté avant que le composant ne soit démonté.
Ils causent de nombreux problèmes, notamment :
Par conséquent, il est nécessaire d'éliminer les problèmes de fuite de mémoire.
C'est une fonction du crochet useEffect
qui nous permet d'arrêter les effets secondaires qui n'ont plus besoin d'être exécutés avant que notre composant ne soit démonté.
useEffect
est construit de telle manière que nous pouvons renvoyer une fonction à l'intérieur et cette fonction de retour est l'endroit où le nettoyage se produit.
Par exemple, le composant A demande à l'API d'obtenir une liste de produits, mais lors de cette demande asynchrone, le composant A est supprimé du DOM (il est démonté). Il n'est pas nécessaire de compléter cette requête asynchrone.
Ainsi, en tant que méthode de nettoyage pour améliorer votre application, vous pouvez nettoyer (annuler) la requête asynchrone afin qu'elle ne soit pas terminée.
useEffect
:
useEffect(() => { // Your effect return () => { // Cleanup } }, [input])
Il existe différentes façons d'annuler les appels de demande de récupération, nous pouvons utiliser fetch AbortController
ou Axios AbortController.
Pour utiliser AbortController
, nous devons créer un contrôleur en utilisant le constructeur AbortController()
. Ensuite, lorsque notre requête de récupération est lancée, nous transmettons AbortSignal
en tant qu'option dans l'objet d' options
de la requête.
Cela associe le contrôleur et le signal à la requête de récupération et nous permet de l'annuler à tout moment en utilisant AbortController.abort()
:
useEffect(() => { //create a controller let controller = new AbortController(); (async () => { try { const response = await fetch(API, { // connect the controller with the fetch request signal: controller.signal, }, ); // handle success setList(await response.json()); // remove the controller controller = null; } catch (e) { // Handle the error } })(); //aborts the request when the component umounts return () => controller?.abort(); },[]);
useEffect(() => { // create a controller const controller = new AbortController(); axios .get(API, { signal: controller.signal }) .then({data}) => { // handle success setList(data); }) .catch((err) => { // Handle the error }); //aborts the request when the component umounts return () => controller?.abort(); }, []);
Lors de l'utilisation des fonctions de minuterie setTimeout(callback, time)
, nous pouvons les effacer lors du démontage en utilisant la fonction spéciale clearTimeout(timerId)
.
useEffect(() => { let timerId = setTimeout(() => { // do something timerId = null; }, 3000); // cleanup the timmer when component unmout return () => clearTimeout(timerId); }, []);
Comme les Timeouts, les setIntervals(callback, time)
ont une fonction spéciale pour les nettoyer avec la fonction clearInterval(intervalId)
.
useEffect(() => { let intervalId = setInterval(() => { // do something like update the state }, 1000); // cleanup the timer when component unmout return () => clearInterval(interval); }, []);
Le nettoyage des écouteurs se fait via window.removeEventListener
. L'appel removeEventListener
doit faire référence à la même fonction dans l'appel removeEventListener
pour supprimer correctement l'écouteur.
useEffect(() => { // function to add to EventListener const handleKeyUp= (event) => { switch (event.key) { case "Escape": setCollapsed(true); break; } } window.addEventListener("keyup", handleKeyUp); // cleanup the listener when component unmout return () => window.removeEventListener("keyup", handleKeyUp); }, []);
Lorsque vous créez unsocket.close()
.
useEffect(() => { const ws = new WebSocket(url, protocols) // do what you want with the socket ws.onmessage = (event) => { setValue(JSON.parse(event.data)); }; // cleanup the web socket when component unmout return () => ws.close() }, [])
Nous avons appris que certains effets secondaires nécessitent un nettoyage pour éviter les fuites de mémoire et les comportements inutiles et indésirables. Nous devons apprendre quand et comment utiliser la fonction de nettoyage du crochet useEffect
pour éviter ces problèmes et optimiser les applications.
Je recommande de nettoyer les effets asynchrones lorsque le composant est démonté. De plus, si l'effet secondaire asynchrone dépend des valeurs d'accessoire ou d'état, envisagez également de les nettoyer lorsque le composant est mis à jour.
J'espère que vous avez trouvé cet article utile et que vous pouvez maintenant utiliser correctement la fonction de nettoyage.
Lire la suite:
Également publié ici .