Synchronisation avec les Effets
Certains composants doivent se synchroniser avec des systèmes externes. Par exemple, vous pourriez vouloir contrôler un composant non-React en fonction de l'état React, établir une connexion serveur, ou envoyer un log d'analyse lorsqu'un composant apparaît à l'écran.Les Effetsvous permettent d'exécuter du code après le rendu afin de synchroniser votre composant avec un système extérieur à React.
Vous allez apprendre
- Ce que sont les Effets
- En quoi les Effets diffèrent des événements
- Comment déclarer un Effet dans votre composant
- Comment éviter de ré-exécuter un Effet inutilement
- Pourquoi les Effets s'exécutent deux fois en développement et comment les corriger
Que sont les Effets et en quoi diffèrent-ils des événements ?
Avant d'aborder les Effets, vous devez être familier avec deux types de logique à l'intérieur des composants React :
- Le code de rendu(introduit dansDécrire l'interface utilisateur) se trouve au niveau supérieur de votre composant. C'est là que vous prenez les props et l'état, les transformez, et retournez le JSX que vous voulez voir à l'écran.Le code de rendu doit être pur.Comme une formule mathématique, il ne doit quecalculerle résultat, sans rien faire d'autre.
- Les gestionnaires d'événements(introduits dansAjouter de l'interactivité) sont des fonctions imbriquées dans vos composants quifontdes choses plutôt que de simplement les calculer. Un gestionnaire d'événements peut mettre à jour un champ de saisie, envoyer une requête HTTP POST pour acheter un produit, ou naviguer l'utilisateur vers un autre écran. Les gestionnaires d'événements contiennent des« effets de bord »(ils changent l'état du programme) causés par une action utilisateur spécifique (par exemple, un clic de bouton ou une saisie).
Parfois, cela ne suffit pas. Imaginez un composantChatRoomqui doit se connecter au serveur de chat chaque fois qu'il est visible à l'écran. Se connecter à un serveur n'est pas un calcul pur (c'est un effet de bord) donc cela ne peut pas se produire pendant le rendu. Cependant, il n'y a pas d'événement particulier unique comme un clic qui cause l'affichage duChatRoom.
Les Effetsvous permettent de spécifier des effets de bord qui sont causés par le rendu lui-même, plutôt que par un événement particulier.Envoyer un message dans le chat est unévénementcar il est directement causé par l'utilisateur cliquant sur un bouton spécifique. Cependant, établir une connexion serveur est unEffetcar cela devrait se produire quelle que soit l'interaction qui a causé l'apparition du composant. Les Effets s'exécutent à la fin d'uncommitaprès la mise à jour de l'écran. C'est le bon moment pour synchroniser les composants React avec un système externe (comme le réseau ou une bibliothèque tierce).
Note
Ici et dans la suite de ce texte, le terme « Effet » avec une majuscule fait référence à la définition spécifique à React ci-dessus, c'est-à-dire un effet de bord causé par le rendu. Pour désigner le concept de programmation plus large, nous dirons « effet de bord ».
Vous n'avez peut-être pas besoin d'un Effet
Ne vous précipitez pas pour ajouter des Effets à vos composants.Gardez à l'esprit que les Effets sont typiquement utilisés pour « sortir » de votre code React et se synchroniser avec un systèmeexterne. Cela inclut les API du navigateur, les widgets tiers, le réseau, etc. Si votre Effet ajuste seulement un état en fonction d'un autre état,vous n'avez peut-être pas besoin d'un Effet.
Comment écrire un Effet
Pour écrire un Effet, suivez ces trois étapes :
- Déclarez un Effet.Par défaut, votre Effet s'exécutera après chaquecommit.
- Spécifiez les dépendances de l'Effet.La plupart des Effets ne doivent se ré-exécuter quequand c'est nécessaireplutôt qu'après chaque rendu. Par exemple, une animation de fondu entrant ne devrait se déclencher que lorsqu'un composant apparaît. Se connecter et se déconnecter d'une salle de chat ne devrait se produire que lorsque le composant apparaît et disparaît, ou lorsque la salle de chat change. Vous apprendrez à contrôler cela en spécifiant desdépendances.
- Ajoutez un nettoyage si nécessaire.Certains Effets doivent spécifier comment arrêter, annuler ou nettoyer ce qu'ils faisaient. Par exemple, « connecter » nécessite « déconnecter », « s'abonner » nécessite « se désabonner », et « récupérer » nécessite soit « annuler » soit « ignorer ». Vous apprendrez à faire cela en retournant unefonction de nettoyage.
Examinons chacune de ces étapes en détail.
Étape 1 : Déclarer un Effet
Pour déclarer un Effet dans votre composant, importez leHook useEffectde React :
Ensuite, appelez-le au niveau supérieur de votre composant et placez du code à l'intérieur de votre Effet :
Chaque fois que votre composant s'affiche, React mettra à jour l'écranpuisexécutera le code à l'intérieur deuseEffect. En d'autres termes,useEffect« retarde » l'exécution d'un morceau de code jusqu'à ce que cet affichage soit reflété à l'écran.
Voyons comment utiliser un Effet pour se synchroniser avec un système externe. Prenons un composant React<VideoPlayer>. Il serait pratique de contrôler s'il est en lecture ou en pause en lui passant une propisPlaying :
Votre composant personnaliséVideoPlayeraffiche la balise navigateur intégrée<video> :
Cependant, la balise navigateur<video>n'a pas de propisPlaying. La seule façon de la contrôler est d'appeler manuellement les méthodesplay()etpause()sur l'élément DOM.Vous devez synchroniser la valeur de la propisPlaying, qui indique si la vidéodevraitêtre en cours de lecture, avec des appels commeplay()etpause().
Nous devons d'abordobtenir une refvers le nœud DOM<video>.
Vous pourriez être tenté d'essayer d'appelerplay()oupause()pendant le rendu, mais ce n'est pas correct :
La raison pour laquelle ce code n'est pas correct est qu'il essaie de faire quelque chose avec le nœud DOM pendant le rendu. Dans React,le rendu doit être un calcul purde JSX et ne doit pas contenir d'effets de bord comme la modification du DOM.
De plus, lorsqueVideoPlayerest appelé pour la première fois, son DOM n'existe pas encore ! Il n'y a pas encore de nœud DOM sur lequel appelerplay()oupause(), car React ne sait pas quel DOM créer avant que vous ne retourniez le JSX.
La solution ici est deencapsuler l'effet de bord avecuseEffectpour le sortir du calcul de rendu :
En encapsulant la mise à jour du DOM dans un Effet, vous laissez React mettre d'abord à jour l'écran. Ensuite, votre Effet s'exécute.
Lorsque votre composantVideoPlayers'affiche (soit la première fois, soit lors d'un ré-affichage), plusieurs choses se produiront. D'abord, React mettra à jour l'écran, en s'assurant que la balise<video>est dans le DOM avec les bonnes props. Ensuite, React exécutera votre Effet. Enfin, votre Effet appelleraplay()oupause()en fonction de la valeur deisPlaying.
Appuyez plusieurs fois sur Lecture/Pause et observez comment le lecteur vidéo reste synchronisé avec la valeur deisPlaying :
Dans cet exemple, le « système externe » que vous avez synchronisé avec l'état React était l'API média du navigateur. Vous pouvez utiliser une approche similaire pour encapsuler du code non-React hérité (comme des plugins jQuery) dans des composants React déclaratifs.
Notez que le contrôle d'un lecteur vidéo est beaucoup plus complexe en pratique. L'appel àplay()peut échouer, l'utilisateur peut lire ou mettre en pause en utilisant les contrôles intégrés du navigateur, etc. Cet exemple est très simplifié et incomplet.
Piège
Par défaut, les Effets s'exécutent aprèschaquerendu. C'est pourquoi un code comme celui-ci vacréer une boucle infinie :
Les Effets s'exécutent commerésultatd'un rendu. Définir un étatdéclencheun rendu. Définir un état immédiatement dans un Effet, c'est comme brancher une prise électrique sur elle-même. L'Effet s'exécute, il définit l'état, ce qui provoque un nouveau rendu, ce qui fait s'exécuter l'Effet, il définit à nouveau l'état, cela provoque un autre rendu, et ainsi de suite.
Les Effets devraient généralement synchroniser vos composants avec un systèmeexterne. S'il n'y a pas de système externe et que vous voulez seulement ajuster un état en fonction d'un autre état,vous n'avez peut-être pas besoin d'un Effet.
Étape 2 : Spécifier les dépendances de l'Effet
Par défaut, les Effets s'exécutent aprèschaquerendu. Souvent, ce n'estpas ce que vous voulez :
- Parfois, c'est lent. La synchronisation avec un système externe n'est pas toujours instantanée, vous voudrez donc peut-être l'éviter à moins que ce ne soit nécessaire. Par exemple, vous ne voulez pas vous reconnecter au serveur de chat à chaque frappe de touche.
- Parfois, c'est incorrect. Par exemple, vous ne voulez pas déclencher une animation de fondu d'entrée du composant à chaque frappe de touche. L'animation ne devrait se jouer qu'une seule fois, lorsque le composant apparaît pour la première fois.
Pour démontrer le problème, voici l'exemple précédent avec quelques appelsconsole.loget un champ de saisie de texte qui met à jour l'état du composant parent. Remarquez comment la saisie provoque la ré-exécution de l'Effet :
Vous pouvez demander à React desauter la ré-exécution inutile de l'Effeten spécifiant un tableau dedépendancescomme second argument de l'appel àuseEffect. Commencez par ajouter un tableau vide[]à l'exemple ci-dessus à la ligne 14 :
Vous devriez voir une erreur indiquantReact Hook useEffect has a missing dependency: 'isPlaying':
Le problème est que le code à l'intérieur de votre Effetdépend dela propisPlayingpour décider de ce qu'il doit faire, mais cette dépendance n'a pas été explicitement déclarée. Pour corriger ce problème, ajoutezisPlayingau tableau de dépendances :
Maintenant, toutes les dépendances sont déclarées, donc il n'y a pas d'erreur. Spécifier[isPlaying]comme tableau de dépendances indique à React qu'il doit sauter la ré-exécution de votre Effet siisPlayingest identique à ce qu'il était lors du rendu précédent. Avec ce changement, la saisie dans le champ ne provoque pas la ré-exécution de l'Effet, mais appuyer sur Lecture/Pause le fait :
Le tableau de dépendances peut contenir plusieurs dépendances. React ne sautera la ré-exécution de l'Effet que sitoutesles dépendances que vous spécifiez ont exactement les mêmes valeurs que lors du rendu précédent. React compare les valeurs des dépendances en utilisant la comparaisonObject.is. Consultez laréférence de useEffectpour plus de détails.
Notez que vous ne pouvez pas « choisir » vos dépendances.Vous obtiendrez une erreur de lint si les dépendances que vous avez spécifiées ne correspondent pas à ce que React attend en fonction du code à l'intérieur de votre Effet. Cela aide à détecter de nombreux bugs dans votre code. Si vous ne voulez pas qu'un certain code soit ré-exécuté,modifiez le code de l'Effet lui-même pour qu'il n'ait pas « besoin » de cette dépendance.
Piège
Les comportements sans tableau de dépendances et avec un tableau de dépendancesvide[]sont différents :
Nous examinerons de près ce que signifie « montage » dans l'étape suivante.
Étape 3 : Ajouter un nettoyage si nécessaire
Considérez un exemple différent. Vous écrivez un composantChatRoomqui doit se connecter au serveur de chat lorsqu'il apparaît. On vous donne une APIcreateConnection()qui retourne un objet avec les méthodesconnect()etdisconnect(). Comment gardez-vous le composant connecté tant qu'il est affiché à l'utilisateur ?
Commencez par écrire la logique de l'Effet :
Il serait lent de se connecter au chat après chaque nouveau rendu, donc vous ajoutez le tableau de dépendances :
Le code à l'intérieur de l'Effet n'utilise aucune props ou état, donc votre tableau de dépendances est[](vide). Cela indique à React de n'exécuter ce code que lorsque le composant est « monté », c'est-à-dire lorsqu'il apparaît à l'écran pour la première fois.
Essayons d'exécuter ce code :
Cet Effet ne s'exécute qu'au montage, donc vous pourriez vous attendre à voir"✅ Connecting..."imprimé une seule fois dans la console.Cependant, si vous vérifiez la console,"✅ Connecting..."s'affiche deux fois. Pourquoi cela arrive-t-il ?
Imaginez que le composantChatRoomfasse partie d'une application plus grande avec de nombreux écrans différents. L'utilisateur commence son parcours sur la pageChatRoom. Le composant se monte et appelleconnection.connect(). Imaginez ensuite que l'utilisateur navigue vers un autre écran—par exemple, vers la page des paramètres. Le composantChatRoomse démonte. Enfin, l'utilisateur clique sur Retour etChatRoomse remonte. Cela établirait une deuxième connexion—mais la première connexion n'a jamais été détruite ! Au fur et à mesure que l'utilisateur navigue dans l'application, les connexions continueraient de s'accumuler.
Des bugs comme celui-ci sont faciles à manquer sans des tests manuels approfondis. Pour vous aider à les repérer rapidement, en développement, React remonte chaque composant une fois immédiatement après son montage initial.
Voir le log"✅ Connecting..."deux fois vous aide à remarquer le vrai problème : votre code ne ferme pas la connexion lorsque le composant se démonte.
Pour corriger le problème, retournez unefonction de nettoyagedepuis votre Effet :
React appellera votre fonction de nettoyage à chaque fois avant que l'Effet ne s'exécute à nouveau, et une dernière fois lorsque le composant se démonte (est retiré). Voyons ce qui se passe lorsque la fonction de nettoyage est implémentée :
Maintenant, vous obtenez trois logs dans la console en développement :
"✅ Connecting...""❌ Disconnected.""✅ Connecting..."
C'est le comportement correct en développement.En remontant votre composant, React vérifie que naviguer ailleurs et revenir ne casserait pas votre code. Se déconnecter puis se reconnecter est exactement ce qui devrait se passer ! Lorsque vous implémentez bien le nettoyage, il ne devrait pas y avoir de différence visible pour l'utilisateur entre exécuter l'Effet une fois et l'exécuter, le nettoyer, puis l'exécuter à nouveau. Il y a une paire d'appels connecter/déconnecter supplémentaire parce que React sonde votre code à la recherche de bugs en développement. C'est normal—n'essayez pas de le faire disparaître !
En production, vous ne verriez que"✅ Connecting..."imprimé une fois.Le remontage des composants ne se produit qu'en développement pour vous aider à trouver les Effets qui nécessitent un nettoyage. Vous pouvez désactiver leMode Strictpour renoncer au comportement de développement, mais nous recommandons de le garder activé. Cela vous permet de trouver de nombreux bugs comme celui ci-dessus.
Comment gérer le déclenchement de l'Effet deux fois en développement ?
React remonte intentionnellement vos composants en développement pour trouver des bugs comme dans le dernier exemple.La bonne question n'est pas "comment exécuter un Effet une seule fois", mais "comment corriger mon Effet pour qu'il fonctionne après un remontage".
Généralement, la réponse est d'implémenter la fonction de nettoyage. La fonction de nettoyage doit arrêter ou annuler ce que l'Effet faisait. La règle générale est que l'utilisateur ne devrait pas pouvoir distinguer entre l'Effet s'exécutant une fois (comme en production) et une séquenceinstallation → nettoyage → installation(comme vous le verriez en développement).
La plupart des Effets que vous écrirez s'inscriront dans l'un des modèles courants ci-dessous.
Piège
N'utilisez pas les refs pour empêcher les Effets de se déclencher
Un piège courant pour empêcher les Effets de se déclencher deux fois en développement est d'utiliser unerefpour empêcher l'Effet de s'exécuter plus d'une fois. Par exemple, vous pourriez "corriger" le bug ci-dessus avec unuseRef:
Cela fait que vous ne voyez"✅ Connecting..."qu'une seule fois en développement, mais cela ne corrige pas le bug.
Lorsque l'utilisateur navigue ailleurs, la connexion n'est toujours pas fermée et lorsqu'il revient, une nouvelle connexion est créée. Au fur et à mesure que l'utilisateur navigue dans l'application, les connexions continueraient de s'accumuler, comme avant la "correction".
Pour corriger le bug, il ne suffit pas de faire en sorte que l'Effet s'exécute une seule fois. L'effet doit fonctionner après un remontage, ce qui signifie que la connexion doit être nettoyée comme dans la solution ci-dessus.
Voir les exemples ci-dessous pour savoir comment gérer les modèles courants.
Contrôler des widgets non-React
Parfois, vous devez ajouter des widgets d'interface utilisateur qui ne sont pas écrits en React. Par exemple, disons que vous ajoutez un composant de carte à votre page. Il a une méthodesetZoomLevel(), et vous souhaitez garder le niveau de zoom synchronisé avec une variable d'étatzoomLeveldans votre code React. Votre Effet ressemblerait à ceci :
Notez qu'aucun nettoyage n'est nécessaire dans ce cas. En développement, React appellera l'Effet deux fois, mais ce n'est pas un problème car appelersetZoomLeveldeux fois avec la même valeur ne fait rien. Cela peut être légèrement plus lent, mais cela n'a pas d'importance car il ne sera pas remonté inutilement en production.
Certaines API peuvent ne pas permettre de les appeler deux fois de suite. Par exemple, la méthodeshowModalde l'élément natif<dialog>lève une exception si vous l'appelez deux fois. Implémentez la fonction de nettoyage et faites-la fermer la boîte de dialogue :
En développement, votre Effet appellerashowModal(), puis immédiatementclose(), et ensuiteshowModal()à nouveau. Cela a le même comportement visible par l'utilisateur que d'appelershowModal()une fois, comme vous le verriez en production.
S'abonner à des événements
Si votre Effet s'abonne à quelque chose, la fonction de nettoyage doit se désabonner :
En développement, votre Effet appelleraaddEventListener(), puis immédiatementremoveEventListener(), et ensuiteaddEventListener()à nouveau avec le même gestionnaire. Ainsi, il n'y aura qu'un seul abonnement actif à la fois. Cela a le même comportement visible par l'utilisateur que d'appeleraddEventListener()une fois, comme en production.
Déclencher des animations
Si votre Effet anime quelque chose, la fonction de nettoyage doit réinitialiser l'animation aux valeurs initiales :
En développement, l'opacité sera définie sur1, puis sur0, et ensuite sur1à nouveau. Cela devrait avoir le même comportement visible par l'utilisateur que de la définir directement sur1, ce qui se produirait en production. Si vous utilisez une bibliothèque d'animation tierce prenant en charge l'interpolation, votre fonction de nettoyage doit réinitialiser la chronologie à son état initial.
Récupération de données
Si votre Effet récupère des données, la fonction de nettoyage doit soitannuler la récupérationsoit ignorer son résultat :
Vous ne pouvez pas « annuler » une requête réseau qui a déjà eu lieu, mais votre fonction de nettoyage doit s'assurer que la récupération qui n'estplus pertinentene continue pas à affecter votre application. Si leuserIdpasse de'Alice' à 'Bob', le nettoyage garantit que la réponse pour'Alice'est ignorée même si elle arrive après celle pour'Bob'.
En développement, vous verrez deux récupérations dans l'onglet Réseau.Il n'y a rien de mal à cela. Avec l'approche ci-dessus, le premier Effet sera immédiatement nettoyé, donc sa copie de la variableignoresera définie surtrue. Ainsi, même s'il y a une requête supplémentaire, elle n'affectera pas l'état grâce à la vérificationif (!ignore).
En production, il n'y aura qu'une seule requête.Si la deuxième requête en développement vous dérange, la meilleure approche est d'utiliser une solution qui déduplique les requêtes et met en cache leurs réponses entre les composants :
Cela améliorera non seulement l'expérience de développement, mais rendra également votre application plus rapide. Par exemple, l'utilisateur qui appuie sur le bouton Retour n'aura pas à attendre que certaines données se rechargent car elles seront mises en cache. Vous pouvez soit créer un tel cache vous-même, soit utiliser l'une des nombreuses alternatives à la récupération manuelle dans les Effets.
Envoi d'analytiques
Considérez ce code qui envoie un événement d'analyse lors de la visite de la page :
En développement,logVisitsera appelé deux fois pour chaque URL, vous pourriez donc être tenté d'essayer de corriger cela.Nous recommandons de laisser ce code tel quel.Comme dans les exemples précédents, il n'y a pas de différence de comportementvisible par l'utilisateurentre l'exécuter une fois et l'exécuter deux fois. D'un point de vue pratique,logVisitne devrait rien faire en développement car vous ne voulez pas que les logs des machines de développement faussent les métriques de production. Votre composant est remonté à chaque fois que vous sauvegardez son fichier, donc il enregistre de toute façon des visites supplémentaires en développement.
En production, il n'y aura pas de doublons dans les logs de visites.
Pour déboguer les événements d'analyse que vous envoyez, vous pouvez déployer votre application dans un environnement de préproduction (qui s'exécute en mode production) ou désactiver temporairement leMode Strictet ses vérifications de remontage spécifiques au développement. Vous pouvez également envoyer des analytiques depuis les gestionnaires d'événements de changement de route au lieu des Effets. Pour des analytiques plus précises, lesobservateurs d'intersectionpeuvent aider à suivre quels composants sont dans la fenêtre d'affichage et combien de temps ils restent visibles.
Pas un Effet : Initialisation de l'application
Certaines logiques ne doivent s'exécuter qu'une seule fois au démarrage de l'application. Vous pouvez les placer en dehors de vos composants :
Cela garantit que cette logique ne s'exécute qu'une seule fois après que le navigateur a chargé la page.
Pas un Effet : Achat d'un produit
Parfois, même si vous écrivez une fonction de nettoyage, il est impossible d'empêcher les conséquences visibles pour l'utilisateur de l'exécution de l'Effet deux fois. Par exemple, peut-être que votre Effet envoie une requête POST comme l'achat d'un produit :
Vous ne voudriez pas acheter le produit deux fois. Cependant, c'est aussi pourquoi vous ne devriez pas mettre cette logique dans un Effet. Et si l'utilisateur va sur une autre page puis appuie sur Retour ? Votre Effet s'exécuterait à nouveau. Vous ne voulez pas acheter le produit lorsque l'utilisateurvisiteune page ; vous voulez l'acheter lorsque l'utilisateurcliquesur le bouton Acheter.
L'achat n'est pas causé par le rendu ; il est causé par une interaction spécifique. Il ne doit s'exécuter que lorsque l'utilisateur appuie sur le bouton.Supprimez l'Effet et déplacez votre requête/api/buydans le gestionnaire d'événements du bouton Acheter :
Cela illustre que si le remontage casse la logique de votre application, cela révèle généralement des bugs existants.Du point de vue de l'utilisateur, visiter une page ne devrait pas être différent de la visiter, cliquer sur un lien, puis appuyer sur Retour pour revoir la page. React vérifie que vos composants respectent ce principe en les remontant une fois en développement.
Récapitulatif
Ce bac à sable peut vous aider à « ressentir » comment les Effets fonctionnent en pratique.
Cet exemple utilisesetTimeoutpour programmer un log dans la console avec le texte saisi, qui apparaîtra trois secondes après l'exécution de l'Effet. La fonction de nettoyage annule le délai en attente. Commencez par appuyer sur « Monter le composant » :
Vous verrez d'abord trois logs :Schedule "a" log,Cancel "a" logetSchedule "a" logà nouveau. Trois secondes plus tard, il y aura aussi un log disanta. Comme vous l'avez appris plus tôt, la paire supplémentaire de planification/annulation est due au fait que React remonte le composant une fois en développement pour vérifier que vous avez bien implémenté le nettoyage.
Maintenant, modifiez le champ de saisie pour y écrireabc. Si vous le faites assez rapidement, vous verrezSchedule "ab" logimmédiatement suivi deCancel "ab" logetSchedule "abc" log.React nettoie toujours l'Effet du rendu précédent avant l'Effet du rendu suivant.C'est pourquoi, même si vous tapez rapidement dans le champ, il y a au plus un délai programmé à la fois. Modifiez le champ plusieurs fois et observez la console pour comprendre comment les Effets sont nettoyés.
Tapez quelque chose dans le champ, puis appuyez immédiatement sur « Démonter le composant ». Notez comment le démontage nettoie l'Effet du dernier rendu. Ici, il efface le dernier délai avant qu'il n'ait eu la chance de se déclencher.
Enfin, modifiez le composant ci-dessus et commentez la fonction de nettoyage pour que les délais ne soient pas annulés. Essayez de taperabcderapidement. Que pensez-vous qu'il se passera dans trois secondes ? Est-ce queconsole.log(text)à l'intérieur du délai affichera ladernièretextet produira cinq logsabcde? Essayez pour vérifier votre intuition !
Trois secondes plus tard, vous devriez voir une séquence de logs (a,ab,abc,abcdetabcde) plutôt que cinq logsabcde. Chaque Effet « capture » la valeur detextde son rendu correspondant.Peu importe que l'étattextait changé : un Effet du rendu avectext = 'ab'verra toujours'ab'. En d'autres termes, les Effets de chaque rendu sont isolés les uns des autres. Si vous êtes curieux de savoir comment cela fonctionne, vous pouvez lire sur lesfermetures.
Récapitulatif
- Contrairement aux événements, les Effets sont causés par le rendu lui-même plutôt que par une interaction spécifique.
- Les Effets vous permettent de synchroniser un composant avec un système externe (API tierce, réseau, etc.).
- Par défaut, les Effets s'exécutent après chaque rendu (y compris le rendu initial).
- React ignorera l'Effet si toutes ses dépendances ont les mêmes valeurs que lors du dernier rendu.
- Vous ne pouvez pas « choisir » vos dépendances. Elles sont déterminées par le code à l'intérieur de l'Effet.
- Un tableau de dépendances vide (
[]) correspond au « montage » du composant, c'est-à-dire lorsqu'il est ajouté à l'écran. - En Mode Strict, React monte les composants deux fois (en développement uniquement !) pour tester la robustesse de vos Effets.
- Si votre Effet dysfonctionne à cause d'un remontage, vous devez implémenter une fonction de nettoyage.
- React appellera votre fonction de nettoyage avant que l'Effet ne s'exécute la prochaine fois, et lors du démontage.
Try out some challenges
Challenge 1 of 4:Focus a field on mount #
In this example, the form renders a <MyInput /> component.
Use the input’s focus() method to make MyInput automatically focus when it appears on the screen. There is already a commented out implementation, but it doesn’t quite work. Figure out why it doesn’t work, and fix it. (If you’re familiar with the autoFocus attribute, pretend that it does not exist: we are reimplementing the same functionality from scratch.)
To verify that your solution works, press “Show form” and verify that the input receives focus (becomes highlighted and the cursor is placed inside). Press “Hide form” and “Show form” again. Verify the input is highlighted again.
MyInput should only focus on mount rather than after every render. To verify that the behavior is right, press “Show form” and then repeatedly press the “Make it uppercase” checkbox. Clicking the checkbox should not focus the input above it.
