Les hooks React ont été publiés il y a 6 ans, mais jusqu'à aujourd'hui, nous pouvons voir des erreurs commises, même par des ingénieurs React expérimentés. Dans la dernière version de React Docs, l'équipe principale a déployé de gros efforts pour enseigner les mauvais cas d'utilisation de useEffect, mais des erreurs continuent de se produire dans des projets réels.
Dans cet article, essayons une approche différente. Comprenons la relation React avec la dérivation et pourquoi vous devriez en utiliser davantage.
React n'est pas entièrement réactif, mais en fin de compte, pour le développeur qui crée des applications, cela n'a pas tellement d'importance. Le point de différence ici est que l'approche grossière suivie par React crée la nécessité de re-rendus pour vraiment identifier les changements créés par la transition d'état.
Alors, pensez à un simple composant React comme celui-ci :
function Example() { const [count, setCount] = useState(0) const text = `count is ${count}`; return ( <button onClick={() => setCount((count) => count + 1)}> {text} </button> ); }
Lorsque nous modifions l'état du comptage, en appelant setCount, nous mettons à jour la valeur de l'état et planifions un nouveau rendu. Très bien, React restituera ce composant en l'appelant à nouveau. En ce moment, si je demande à React ce qui a changé sur le rendu, quelle devrait être la réponse ?
Probablement un humble « Je ne sais pas ».
React ne suit pas son état avec une structure de données complexe gérant ses dépendances comme le font d'autres bibliothèques réactives à granularité fine. React doit appeler à nouveau le composant. Dans ce nouvel appel, la constante de comptage créée aura la nouvelle valeur, et au-dessus nous créerons une nouvelle constante avec la chaîne, par exemple « count is 1 », si la valeur de count est passée à 1.
Ensuite, le JSX générera sa structure avec un seul changement, le texte intérieur du bouton n'est pas « le nombre est de 1 », React effectue le processus de réconciliation, identifie ce changement et l'applique au vrai DOM. Évident, non ?
À ce moment-là, si je demande à React ce qui a changé, il répondra probablement : « Le texte du bouton de l'exemple de composant ».
Mais attendez, qu'en est-il de la constante texte ? Cela a également changé, pourquoi la structure v-dom (je connais les problèmes avec ce terme, mais c'est ainsi qu'on l'appelle communément) est-elle importante ?
Pour React, peu importe les variables et constantes que vous avez créées en interne. Ce qui compte, c'est le changement d'état puis le retour de l'appel du composant.
Tout ce qui se trouve au milieu fait partie du processus de création de la structure de la vue. Bien sûr, toutes ces données peuvent affecter le retour JSX, et c'est l'intérêt du modèle React, se soucier du résultat des appels de composants et mettre à jour le DOM en conséquence avec la vue.
Vous avez probablement vu la simplification du modèle React comme :
function Example() { const [count, setCount] = useState(0) const text = `count is ${count}`; return ( <button onClick={() => setCount((count) => count + 1)}> {text} </button> ); }
Voir comme le résultat de la fonction de l'état. Dans ce cas, la vue est une dérivation qui change en fonction de l'état. Ainsi, pour ce terme et pour les données des composants internes, React est une machine de dérivation.
Chaque variable et constante que vous avez créées dans un composant sera simplement active pendant l'appel de ce composant. Dans l'exemple que nous avons utilisé ci-dessus, chaque nouveau rendu des composants d'exemple créait un nouveau texte constant. Si j'ai besoin d'une nouvelle valeur basée sur certains accessoires ou états, cela créera simplement une nouvelle variable en utilisant ces états et accessoires dans le calcul.
Prenons un exemple tiré de la documentation React :
view= f(state)
Nous avons quelques problèmes ici. Tout d'abord, la nature d'un État.
Pourquoi avons-nous besoin d'un état local comme celui-ci dans une application ? Pour conserver les données et permettre à l'utilisateur de les modifier. L'état fullName n'est pas modifié par l'utilisateur, mais par useEffect. C’est utiliser d’autres états pour créer une nouvelle valeur. Encore une fois, dans React, chaque variable et constante que nous créons en interne dans le composant peut utiliser les états et les accessoires pour calculer sa valeur : une dérivation, le comportement par défaut de React.
Il y a un autre problème avec cet exemple, concernant le temps d'exécution. Dans ce cas, lors du premier rendu, la valeur fullName sera une chaîne vide. React obtiendra le retour du JSX de ce composant, le rendra dans l'interface utilisateur, suivra le processus de peinture du navigateur et après cela, appellera les useEffects des composants. À ce moment-là, nous aurons l'appel setfullName, qui planifiera un nouveau rendu. React appellera à nouveau le composant, maintenant avec le nom complet comme Taylor Swift, puis mettra à jour l'interface utilisateur avec la nouvelle valeur de texte.
En termes d'exécution, vous effectuez 2 rendus, dont un inutile, avec des données erronées. C'est pire en termes de performances et de stabilité, car l'utilisateur verra la valeur comme vide et cela peut être vu comme un bug visuel.
Donc, en suivant le modèle de dérivation React, nous pouvons simplement le changer en :
function Form() { const [firstName, setFirstName] = useState('Taylor'); const [lastName, setLastName] = useState('Swift'); // ? Avoid: redundant state and unnecessary Effect const [fullName, setFullName] = useState(''); useEffect(() => { setFullName(firstName + ' ' + lastName); }, [firstName, lastName]); //... return <span>{fullName}</span>; }
Maintenant, nous n'avons qu'un seul rendu, évitant ainsi le rendu inutile. Et nous éviterons d’utiliser l’effet simplement en utilisant une dérivation. Cela sera mis à jour à chaque nouveau rendu en utilisant la dernière version des valeurs d'état.
Bien, dans ce cas, utilisez simplement useMemo, en ajoutant le même tableau de dépendances que vous utilisiez sur useEffect. Le modèle de mémorisation de React n'est qu'un moyen d'éviter le comportement par défaut, c'est-à-dire de créer une nouvelle dérivation à chaque nouveau rendu. Avec useMemo, vous suivez manuellement les états et les accessoires et créez simplement à nouveau la dérivation si certains d'entre eux ont changé.
useEffect est nécessaire pour la synchronisation externe sur les changements de valeurs. Concernant le développement de l'interface utilisateur, il existe très peu de rares cas où cela a du sens, car normalement les changements externes, tels que les appels d'API du serveur, se produisent sur les actions de l'utilisateur (nous créons des interfaces utilisateur, d'ailleurs), donc cela se produira sur les gestionnaires d'événements, pas dans un useEffect.
Si vous utilisez useEffect pour mettre à jour un état, vous pouvez probablement effectuer la même mise à jour en utilisant la dérivation, évitant ainsi tous les problèmes mentionnés précédemment.
Si la dérivation ne fonctionne pas, ou si vous avez l'un des rares cas spécifiques, ou si quelque chose ne va pas avec la conception de l'État ou avec la solution elle-même. Cela ne pose aucun problème, mais dans ces cas, il est préférable de revoir le composant et d'éviter de futurs problèmes avec le code du composant.
Ce sont les bases de la dérivation dans React, mais il nous manque quelque chose ici.
Que se passe-t-il lorsque je dois effectuer une dérivation asynchrone, comme une simple requête GET, qui utilise un état comme paramètre et doit être recalculée à chaque fois que l'état change ?
C'est un sujet pour le prochain article.
À bientôt !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!