Introduction aux crochets React



Si vous lisez Twitter, vous savez très probablement que Hooks est une nouvelle fonctionnalité de React, mais vous pouvez vous demander, comment pouvons-nous les utiliser dans la pratique ? Dans cet article, nous allons vous montrer quelques exemples d'utilisation de crochets.
L'une des idées clés à comprendre est que les hooks vous permettent d'utiliser l'état et d'autres fonctionnalités de React sans écrire de classes .

La motivation derrière les crochets


Bien que l'architecture orientée composants nous permette de réutiliser la vue dans notre application, l'un des plus gros problèmes auxquels un développeur est confronté est de savoir comment réutiliser la logique basée sur l'état entre les composants . Lorsque nous avons des composants qui ont une logique d'état similaire, il n'y a pas de bonnes solutions pour réutiliser des composants, ce qui peut parfois entraîner une duplication de la logique dans les méthodes du constructeur et du cycle de vie.
Pour résoudre ce problème, utilisez généralement:

  • Composants d'ordre élevé
  • accessoires de rendu

Mais ces deux modèles présentent des inconvénients qui peuvent contribuer à la complexité de la base de code.

Les crochets visent à résoudre tous ces problèmes, vous permettant d'écrire des composants fonctionnels qui ont accès à l'état, au contexte, aux méthodes de cycle de vie, à la référence, etc., sans écrire de classes.

Crochets en Alpha


Avant de plonger, il est important de mentionner que le développement de l'API Hooks n'est pas encore terminé.

De plus, la documentation officielle est très bonne, et nous vous recommandons de la lire également car elle décrit en détail la motivation derrière l'introduction de Hooks.
UPD L'article original, dont vous lisez la traduction, a été écrit à une époque où cette API était en test alpha, au moment où React Hooks est officiellement prêt à l'emploi. Des modifications irréversibles apportées à la version (par rapport à alpha) peuvent être trouvées au bas de l'article ou dans les notes de version .

Comment les crochets se rapportent aux classes


Si vous connaissez React, l'une des meilleures façons de comprendre les hooks est de voir comment nous pouvons reproduire le comportement que nous avons l'habitude de travailler avec des classes utilisant des hooks.

Rappelons que lors de l'écriture de classes de composants, nous devons souvent:

  • Gérer l'état
  • Utilisez des méthodes de cycle de vie comme componentDidMount () et componentDidUpdate ()
  • Contexte d'accès (contextType statique)


Avec React Hooks, nous pouvons reproduire un comportement similaire dans les composants fonctionnels:

  • Pour utiliser l'état d'un composant, utilisez le crochet useState ()
  • Au lieu d'utiliser des méthodes de cycle de vie telles que componentDidMount () et componentDidUpdate (), utilisez le crochet useEffect ().
  • Au lieu d'utiliser la propriété contextType statique, utilisez le hook useContext ().

La dernière version de React est requise pour utiliser les crochets.


Vous pouvez commencer avec Hooks dès maintenant en changeant la valeur de react et react-dom dans votre package.json en «suivant».



Exemple de crochet UseState ()


L'État fait partie intégrante de React. Il nous permet de déclarer des variables qui contiennent des données qui, à leur tour, seront utilisées dans notre application. À l'aide de classes, l'état est généralement défini comme suit:



Avant Hooks, l'état était généralement utilisé uniquement dans un composant - une classe, mais, comme mentionné ci-dessus, Hooks nous permet également d'ajouter l'état à un composant fonctionnel .
Voyons un exemple ci-dessous. Ici, nous construisons un commutateur rétro-éclairé qui change de couleur en fonction de la valeur de l'état. Pour cela, nous utiliserons hook useState ().
Voici le code complet (et un exemple exécutable) - nous verrons ce qui se passe ci-dessous. En cliquant sur l'image, vous pouvez regarder cet exemple sur CodeSandBox.



Notre composant est une fonction


Dans le bloc de code ci-dessus, nous commençons par importer useState de React. UseState est une nouvelle façon de profiter des possibilités que cet état pourrait offrir.
Notez ensuite que ce composant est une fonction, pas une classe . Intéressant!

État de lecture et d'écriture


A l'intérieur de cette fonction, nous appelons useState pour créer une variable dans l'état:



useState est utilisé pour déclarer une variable d'état et peut être initialisé avec n'importe quel type de valeur (contrairement à l'état dans les classes, qui devrait être un objet).

Comme vu ci-dessus, nous utilisons la déstructuration sur la valeur de retour de useState.
  • La première valeur, légère dans ce cas, est l'état actuel (comme this.state)
  • La deuxième valeur est la fonction utilisée pour mettre à jour la valeur d'état (première valeur) (comme this.setState).

Ensuite, nous créons deux fonctions, chacune définissant l'état sur des valeurs différentes, 0 ou 1.



Ensuite, nous les appliquons en tant que gestionnaires d'événements sur les boutons de la vue:



React suit l'état


Lorsque le bouton «On» est enfoncé, la fonction setOn est appelée, qui appelle setLight (1). L'appel à setLight (1) met à jour la valeur de la lumière pour le prochain rendu . Cela peut sembler un peu magique, mais React garde une trace de la valeur de cette variable et passera une nouvelle valeur lorsque ce composant sera rendu.
Ensuite, nous utilisons l'état actuel ( lumière ) pour déterminer si la lampe doit être allumée ou non. Autrement dit, nous définissons la couleur de remplissage du SVG en fonction de la valeur de la lumière . Si la lumière est 0 (désactivée), fillColor est définie sur # 000000 (et si elle est 1 (activée), fillColor est définie sur # ffbb73).

Plusieurs états


Bien que nous ne le fassions pas dans l'exemple ci-dessus, vous pouvez créer plusieurs états en appelant useState plusieurs fois. Par exemple:



REMARQUE
Il existe certaines limites à l'utilisation des crochets dont vous devez être conscient. Plus important encore, vous ne devez appeler des hooks qu'au niveau supérieur de votre fonction. Voir « Règles des crochets » pour plus d'informations.


Exemple de crochet UseEffect ()


UseEffect Hook vous permet d'effectuer des effets secondaires dans les composants fonctionnels . Les effets secondaires peuvent inclure l'accès à l'API, la mise à jour du DOM, l'abonnement aux gestionnaires d'événements - tout ce que vous voulez, c'est qu'une action «impérative» se produise.

À l'aide du hook useEffect (), React sait que vous souhaitez effectuer une action spécifique après le rendu.

Regardons un exemple ci-dessous. Nous utiliserons useEffect () pour appeler l'API et obtenir une réponse.



Cet exemple de code utilise à la fois useState et useEffect , et c'est parce que nous voulons écrire le résultat de l'appel d'API à state.



Recevoir des données et mettre à jour l'état


Pour «utiliser l'effet», nous devons placer notre action dans la fonction useEffect , c'est-à-dire que nous transmettons l'effet «action» comme une fonction anonyme, comme premier argument à useEffect .
Dans l'exemple ci-dessus, nous faisons référence à une API qui renvoie une liste de noms. Lorsque la réponse revient, nous la convertissons en JSON, puis utilisons setNames (data) pour définir l'état.



Problèmes de performances lors de l'utilisation d'effets



Cependant, il y a autre chose à dire sur l'utilisation de useEffect .

La première chose à penser est que par défaut, notre useEffect sera appelé à chaque rendu! La bonne nouvelle est que nous n'avons pas à nous soucier des données obsolètes, mais la mauvaise nouvelle est que nous ne voulons probablement pas faire de requête HTTP pour chaque rendu (comme dans ce cas).

Vous pouvez ignorer les effets à l'aide du deuxième argument useEffect , comme dans ce cas. Le deuxième argument à useEffect est une liste de variables que nous voulons «observer», puis nous ne réexécuterons l'effet que lorsque l'une de ces valeurs changera.

Dans l'exemple de code ci-dessus, notez que nous transmettons un tableau vide comme deuxième argument. C'est nous qui disons à React que nous ne voulons nommer cet effet que lors du montage du composant.

Pour en savoir plus sur les performances des effets, consultez cette section dans les livres blancs.

De plus, comme la fonction useState, useEffect vous permet d'utiliser plusieurs instances, ce qui signifie que vous pouvez avoir plusieurs fonctions useEffect.

Exemple de hook UseContext ()


Point de contexte

Le contexte dans React est un moyen pour un composant enfant d'accéder à une valeur dans le composant parent.

Pour comprendre le besoin de contexte: lors de la création d'une application React, vous devez souvent transmettre des valeurs du haut de votre arbre React vers le bas. En n'utilisant pas de contexte, vous passez des accessoires via des composants qui n'ont pas besoin de les connaître.

Passer des accessoires le long de l'arbre de composants «non liés» est affectueusement appelé forage d'accessoires.
React Context résout le problème de forage des accessoires en vous permettant de partager des valeurs via l'arborescence des composants, avec tout composant qui demande ces valeurs.

useContext () simplifie l'utilisation du contexte

Avec useContext Hook, l'utilisation du contexte est plus facile que jamais.

La fonction useContext () prend un objet contextuel, qui est initialement renvoyé par React.createContext () , puis retourne la valeur de contexte actuelle. Regardons un exemple ci-dessous.



Dans le code ci-dessus, le contexte du JediContext est créé à l'aide de React.createContext ().

Nous utilisons JediContext.Provider dans notre composant App et y définissons la valeur "Luke". Cela signifie que tout composant ayant besoin d'accéder au contexte pourra désormais lire cette valeur.

Pour lire cette valeur dans la fonction Display (), nous appelons useContext, en passant l'argument JediContext.

Ensuite, nous transmettons l'objet contextuel que nous avons obtenu de React.createContext, et il affiche automatiquement la valeur. Lorsque la valeur du fournisseur est mise à jour, ce crochet fonctionnera automatiquement avec la dernière valeur de contexte.

Obtenir un lien vers le contexte dans une application plus grande


Ci-dessus, nous avons créé JediContext dans les deux composants, mais dans une application plus grande, Display et App seront dans des fichiers différents. Par conséquent, si vous avez une situation similaire, vous vous demandez peut-être: "Comment obtenir un lien vers JediContext entre les fichiers?"

La réponse est que vous devez créer un nouveau fichier qui exporte le JediContext .
Par exemple, vous pourriez avoir un fichier context.js qui contient quelque chose comme ceci:



puis dans App.js (et Display.js), vous devez écrire:



Merci, Dave )

Exemple de crochet UseRef ()


Refs fournit un moyen d'accéder aux éléments React créés dans la méthode render ().
Si vous êtes nouveau dans les références React, vous pouvez lire cette introduction aux références React .
La fonction useRef () renvoie un objet ref.



useRef () et formulaires avec entrée


Voyons un exemple d'utilisation du crochet useRef ().



Dans l'exemple ci-dessus, nous utilisons useRef () en combinaison avec useState () pour rendre la valeur d'entrée à la balise p.

Ref est créé dans la variable nameRef. Ensuite, la variable nameRef peut être utilisée en entrée, donnée comme référence. Essentiellement, cela signifie que maintenant le contenu du champ de saisie sera accessible via ref.

Le bouton d'envoi dans le code a un gestionnaire d'événements onClick appelé submitButton. La fonction submitButton appelle setName (créé via useState).

Comme nous l'avons déjà fait avec hookState, setName sera utilisé pour définir le nom de l'état. Pour extraire le nom de la balise d'entrée, nous lisons la valeur de nameRef.current.value.

Une autre remarque concernant useRef est qu'il peut être utilisé plus que l'attribut ref.

Utilisation de crochets personnalisés


L'une des fonctionnalités les plus intéressantes des crochets est que vous pouvez facilement partager la logique entre plusieurs composants en créant votre propre crochet.

Dans l'exemple ci-dessous, nous allons créer un crochet setCounter () personnalisé qui nous permet de suivre l'état et de fournir des fonctions de mise à jour d'état personnalisées!

Voir également, ce crochet useCounter de react -use et useCounter de Kent




Dans le bloc de code ci-dessus, nous créons une fonction useCounter qui stocke la logique de notre hook.

Veuillez noter que useCounter peut utiliser d'autres crochets! Commençons par créer un nouvel état Hook via useState.

Ensuite, nous définissons deux fonctions d'assistance: incrémenter et décrémenter , qui appellent setCount et ajustent le nombre actuel en conséquence.

Enfin, nous renvoyons les liens nécessaires pour interagir avec notre hook.

Q: Que se passe-t-il en retournant un tableau avec un objet?
R: Eh bien, comme la plupart des choses dans Hooks, les conventions API ne sont pas encore terminées. Mais ce que nous faisons ici renvoie un tableau, où:

  • Le premier élément est la valeur actuelle du crochet.
  • Le deuxième élément est un objet contenant les fonctions utilisées pour interagir avec le crochet.

Cette convention vous permet de «renommer» facilement la valeur actuelle du crochet - comme nous le faisons ci-dessus avec myCount .

Cependant, vous pouvez retourner tout ce que vous voulez de votre crochet personnalisé.

Dans l'exemple ci-dessus, nous utilisons l' incrémentation et la décrémentation comme gestionnaires onClick à notre avis. Lorsque l'utilisateur appuie sur les boutons, le compteur est mis à jour et ré-affiché (comme myCount ) dans la vue.

Écriture de tests pour React Hooks


Pour écrire des tests pour les hooks, nous utiliserons la bibliothèque react-testing- test.

react-testing-library est une solution très légère pour tester les composants React. C'est une extension de react-dom et react-dom / test-utils . L'utilisation de la bibliothèque react-testing garantit que vos tests fonctionnent directement avec les nœuds DOM.

Avec les crochets de test, tout n'est pas encore clair. Actuellement, vous ne pouvez pas tester le hook de manière isolée. Au lieu de cela, vous devez attacher votre crochet au composant et tester ce composant.

Donc, ci-dessous, nous écrirons des tests pour nos crochets, interagissant avec nos composants, et non pas directement avec des crochets. La bonne nouvelle est que nos tests ressembleront à des tests React réguliers.

Test du hook useState ()


Voyons un exemple d'écriture de tests pour useState Hook. Dans le didacticiel ci-dessus, nous testons plus de variantes de l'exemple useState utilisé ci-dessus. Nous écrirons des tests pour nous assurer que le fait d'appuyer sur le bouton «Off» met l'état à 0 et d'appuyer sur le bouton «On» met l'état à 1.



Dans le bloc de code ci-dessus, nous commençons par importer quelques assistants à partir de la bibliothèque react-testing- et du composant sous test.

  • rendu , cela aidera à afficher notre composant. Il est rendu dans un conteneur qui est ajouté au document.body
  • getByTestId obtient l'élément DOM par data-testid
  • fireEvent , il est utilisé pour "déclencher" des événements DOM. Il attache un gestionnaire d'événements pour documenter et traite certains événements DOM via la délégation d'événements, par exemple. en cliquant sur un bouton.

De plus, dans la fonction d'approbation de test, nous définissons les valeurs des variables pour les éléments avec data-testid et leurs valeurs que nous aimerions utiliser dans le test. Avec des liens vers des éléments du DOM, nous pouvons ensuite utiliser la méthode fireEvent pour simuler un clic sur un bouton.

Le test vérifie que si l'on clique sur onButton , la valeur d'état est définie sur 1 et lorsque vous cliquez sur offButton, l' état est 1.

Test du crochet useEffect ()


Dans cet exemple, nous allons écrire des tests pour ajouter un produit au panier en utilisant useEffect Hook. Le nombre d'éléments est également stocké dans localStorage. Le fichier index.js dans CodeSandbox ci-dessous contient la logique réelle utilisée pour ajouter des articles au panier.

Nous allons écrire des tests pour nous assurer que la mise à jour du nombre d'articles du panier est également reflétée dans localStorage, et même si la page se recharge, le nombre d'articles du panier est toujours le même.



Dans la fonction qui confirme le test, nous définissons d'abord cartItem dans localStorage sur 0, ce qui signifie que le nombre d'éléments du panier est 0. Ensuite, nous obtenons à la fois le conteneur et le rendu du composant App via la déstructuration. Le rendu nous permet de simuler des rechargements de page.

Ensuite, nous obtenons les liens vers les boutons et la balise p, qui affiche la valeur actuelle du panier et les définit en variables.

Une fois cela fait, le test simule ensuite un clic sur addButton et vérifie si le compteur de panier actuel est 1 et recharge la page, après quoi s'il vérifie si localStorage , cartItem est défini sur 1. Ensuite, il simule un clic sur resetButton et vérifie si le nombre actuel d'articles du panier est défini sur 0.

Test du crochet useRef ()


Dans cet exemple, nous allons tester useRef Hook, et nous utiliserons l'exemple original useRef ci-dessus comme base pour le test. UseRef est utilisé pour obtenir la valeur du champ de saisie, puis définit la valeur à l'état. Le fichier index.js dans CodeSandbox ci-dessous contient la logique pour entrer une valeur et l'envoyer.



Dans la fonction qui approuve le test, nous définissons les variables dans le champ de saisie, une balise p qui affiche la valeur actuelle de ref et un bouton de soumission. Nous définissons également la valeur que nous souhaitons saisir dans le champ de saisie de la variable newName. Cela sera utilisé pour la vérification dans le test.



La méthode fireEvent.change est utilisée pour entrer une valeur dans le champ de saisie, auquel cas le nom stocké dans la constante newName est utilisé, après quoi le bouton d'envoi est enfoncé.

Le test vérifie ensuite si la valeur ref après avoir appuyé sur le bouton correspond à la valeur de newName .

Enfin, vous devriez voir "Pas de crash de test, félicitations!" message dans la console.

Réponse de la communauté aux crochets


Depuis l'introduction de React Hooks, la communauté est ravie de cette fonctionnalité, et nous avons vu de nombreux exemples et exemples d'utilisation de React Hooks. En voici quelques-uns:

  • Ce site contient une collection de React Hooks.
  • react-use , la bibliothèque livrée avec un tas de React Hooks.
  • Cet exemple CodeSandbox montre comment utiliser useEffect Hook pour créer des animations à l'aide de react -spring
  • Un exemple useMutableReducer qui vous permet de simplement muter un état pour le mettre à jour dans un réducteur.
  • Cet exemple se trouve sur CodeSandbox, qui montre une utilisation intégrée complexe de la communication parent-enfant et l'utilisation de redisers.
  • Composant du commutateur React Hooks
  • Une autre collection de React Hooks qui a des crochets pour les valeurs d'entrée, l'orientation du périphérique et la visibilité du document.


Différents types de crochets


Il existe différents types de crochets que vous pouvez commencer à utiliser dans votre application React. Ils sont listés ci-dessous:

  • useState - nous permet d'écrire des fonctions pures avec accès à l'état en elles.
  • useEffect - nous permet d'effectuer des effets secondaires. Les effets secondaires peuvent être des appels API, la mise à jour du DOM, l'abonnement à des gestionnaires d'événements.
  • useContext - vous permet d'écrire des fonctions pures avec du contexte dedans.
  • useReducer - nous donne un lien vers un réducteur de type Redux
  • useRef - vous permet d'écrire des fonctions pures qui retournent un objet ref mutable.
  • useMemo - .
  • useCallback — Hook .
  • useImperativeMethods - , ref.
  • useMutationEffects — useEffect Hook , DOM-.
  • useLayoutEffect - DOM -.
  • hooks - .


hooks


La grande chose à propos des Hooks est qu'ils fonctionnent côte à côte avec le code existant, vous pouvez donc lentement apporter des modifications qui implémentent Hooks. Tout ce que vous avez à faire est de mettre à niveau React vers une version prenant en charge les hooks.

Cependant, les Hooks sont toujours une fonctionnalité expérimentale, et l'équipe React a averti à plusieurs reprises que l'API est susceptible de changer. Considérez que vous êtes averti.
Que signifie l'émergence des crochets pour les classes? Comme le rapporte l'équipe React, les classes restent toujours, elles sont une partie énorme de la base de code React, et le seront probablement pendant un certain temps à venir.

. Facebook , , , , . React Hooks, —

API- Hooks , Hooks, , .

Ressources supplémentaires


  • React React Hooks,
  • API .
  • RFC, ,


UPD
:
React 16.8 Hooks API. -:
— useMutationEffect.
— useImperativeMethods useImperativeHandle.
— useState useReducer Hooks.
— , useEffect/useMemo/useCallback Hooks.
— Object.is useState useReducer.
— Strict Mode (DEV-only).
— lazy initialization API useReducer Hook.
.

Source: https://habr.com/ru/post/fr429712/


All Articles