Premiers pas avec l'API React Hooks

Publié: 2022-03-10
Résumé rapide ↬ Dans ce didacticiel, vous allez apprendre et comprendre ce que sont les crochets React, les crochets React de base disponibles et également des exemples sur la façon de les écrire pour vos applications React. Au cours du processus, vous découvrirez également certains crochets supplémentaires fournis avec React 16.8 et également comment écrire vos propres crochets React personnalisés.

Lorsque React 16.8 a été publié officiellement début février 2019, il était livré avec une API supplémentaire qui vous permet d'utiliser l'état et d'autres fonctionnalités dans React sans écrire de classe. Cette API supplémentaire s'appelle Hooks et devient populaire dans l'écosystème React, des projets open source à l'utilisation dans les applications de production.

Les React Hooks sont entièrement opt-in, ce qui signifie qu'il n'est pas nécessaire de réécrire le code existant, ils ne contiennent aucune modification avec rupture et ils sont disponibles pour une utilisation avec la version de React 16.8. Certains développeurs curieux ont utilisé l'API Hooks avant même sa sortie officielle, mais à l'époque, elle n'était pas stable et n'était qu'une fonctionnalité expérimentale. Il est désormais stable et recommandé aux développeurs de React.

Note : Nous ne parlerons pas de React ou de JavaScript en général. Une bonne connaissance de ReactJS et de JavaScript vous sera utile tout au long de ce didacticiel.

Que sont les crochets React ?

React Hooks sont des fonctions intégrées qui permettent aux développeurs React d'utiliser des méthodes d'état et de cycle de vie à l'intérieur de composants fonctionnels, ils fonctionnent également avec le code existant, de sorte qu'ils peuvent facilement être adoptés dans une base de code. La façon dont les crochets ont été présentés au public était qu'ils permettaient aux développeurs d'utiliser l'état dans les composants fonctionnels, mais sous le capot, les crochets sont beaucoup plus puissants que cela. Ils permettent aux développeurs React de profiter des avantages suivants :

  • Amélioration de la réutilisation du code ;
  • Meilleure composition de code ;
  • Meilleures valeurs par défaut ;
  • Partager une logique non visuelle avec l'utilisation de crochets personnalisés ;
  • Flexibilité dans le déplacement vers le haut et vers le bas de l'arborescence des components .

Avec React Hooks, les développeurs ont le pouvoir d'utiliser des composants fonctionnels pour presque tout ce qu'ils doivent faire, du simple rendu de l'interface utilisateur à la gestion de l'état et de la logique, ce qui est plutôt soigné.

Motivation derrière la sortie des crochets React

Selon la documentation officielle de ReactJS, voici les motivations derrière la sortie de React Hooks :

  • Réutiliser la logique avec état entre les composants est difficile.
    Avec Hooks, vous pouvez réutiliser la logique entre vos composants sans changer leur architecture ou leur structure.
  • Les composants complexes peuvent être difficiles à comprendre.
    Lorsque les composants deviennent plus gros et effectuent de nombreuses opérations, cela devient difficile à comprendre à long terme. Les hooks résolvent ce problème en vous permettant de séparer un composant unique particulier en plusieurs fonctions plus petites en fonction des éléments de ce composant séparé qui sont liés (comme la configuration d'un abonnement ou la récupération de données), plutôt que d'avoir à forcer une séparation basée sur des méthodes de cycle de vie.
  • Les cours sont assez déroutants.
    Les cours sont un obstacle à l'apprentissage de React correctement ; vous auriez besoin de comprendre comment this fonctionne en JavaScript, ce qui diffère des autres langages. React Hooks résout ce problème en permettant aux développeurs d'utiliser le meilleur des fonctionnalités de React sans avoir à utiliser de classes.
Plus après saut! Continuez à lire ci-dessous ↓

Les règles des crochets

Il y a deux règles principales qui doivent être strictement respectées comme indiqué par l'équipe principale de React dans lesquelles elles ont été décrites dans la documentation de la proposition de crochets.

  • Assurez-vous de ne pas utiliser de crochets à l'intérieur de boucles, de conditions ou de fonctions imbriquées ;
  • N'utilisez que les crochets de l'intérieur des fonctions React.

Crochets de réaction de base

Il y a 10 crochets intégrés qui ont été livrés avec React 16.8 mais les crochets de base (couramment utilisés) incluent :

  • useState()
  • useEffect()
  • useContext()
  • useReducer()

Ce sont les 4 hooks de base couramment utilisés par les développeurs React qui ont adopté React Hooks dans leurs bases de code.

useState()

Le crochet useState() permet aux développeurs de React de mettre à jour, de gérer et de manipuler l'état à l'intérieur des composants fonctionnels sans avoir besoin de le convertir en un composant de classe. Utilisons l'extrait de code ci-dessous est un simple composant de compteur d'âge et nous l'utiliserons pour expliquer la puissance et la syntaxe du crochet useState() .

 function App() { const [age, setAge] = useState(19); const handleClick = () => setAge(age + 1) return <div> I am {age} Years Old <div> <button onClick={handleClick}>Increase my age! </button> </div> </div> }

Si vous avez remarqué, notre composant a l'air assez simple, concis et c'est maintenant un composant fonctionnel et n'a pas non plus le niveau de complexité qu'un composant de classe aurait.

Le crochet useState() reçoit un état initial en tant qu'argument, puis renvoie, en utilisant la déstructuration de tableau en JavaScript, les deux variables du tableau peuvent être nommées quoi. La première variable est l'état réel, tandis que la seconde variable est une fonction destinée à mettre à jour l'état en fournissant un nouvel état.

Notre application React terminée ( Grand aperçu )

Voici à quoi devrait ressembler notre composant lorsqu'il est rendu dans notre application React. En cliquant sur le bouton "Augmenter mon âge", l'état de l'âge changera et le composant fonctionnera comme un composant de classe avec état.

useEffect()

Le useEffect() accepte une fonction qui contiendrait du code efficace. Dans les composants fonctionnels, les effets tels que les mutations, les abonnements, les minuteries, la journalisation et d'autres effets ne sont pas autorisés à être placés dans un composant fonctionnel, car cela entraînerait de nombreuses incohérences lors du rendu de l'interface utilisateur et également des bogues déroutants.

En utilisant le crochet useEffect() , la fonction effective qui lui est transmise s'exécutera juste après l'affichage du rendu à l'écran. Les effets sont essentiellement jetés sur la manière impérative de créer des interfaces utilisateur qui est assez différente de la manière fonctionnelle de React.

Par défaut, les effets sont exécutés principalement une fois le rendu terminé, mais vous avez la possibilité de les déclencher également lorsque certaines valeurs changent.

Le useEffect() est principalement utilisé pour les effets secondaires qui sont généralement utilisés pour les interactions avec l'API Browser/DOM ​​ou la récupération de données ou les abonnements de type API externe. De plus, si vous connaissez déjà le fonctionnement des méthodes de cycle de vie de React, vous pouvez également considérer le crochet useEffect() comme un montage , une mise à jour et un démontage de composants, le tout combiné en une seule fonction. Il nous permet de répliquer les méthodes de cycle de vie dans les composants fonctionnels.

Nous utiliserons les extraits de code ci-dessous pour expliquer la manière la plus simple de le faire en utilisant le useEffect() .

Étape 1 : Définir l'état de votre application

 import React, {useState} from 'react'; function App() { //Define State const [name, setName] = useState({firstName: 'name', surname: 'surname'}); const [title, setTitle] = useState('BIO'); return( <div> <h1>Title: {title}</h1> <h3>Name: {name.firstName}</h3> <h3>Surname: {name.surname}</h3> </div> ); }; export default App

Tout comme nous en avons discuté dans la section précédente sur la façon d'utiliser le crochet useState() pour gérer l'état à l'intérieur des composants fonctionnels, nous l'avons utilisé dans notre extrait de code pour définir l'état de notre application qui affiche mon nom complet.

Étape 2 : appelez le hook useEffect

 import React, {useState, useEffect} from 'react'; function App() { //Define State const [name, setName] = useState({firstName: 'name', surname: 'surname'}); const [title, setTitle] = useState('BIO'); //Call the use effect hook useEffect(() => { setName({FirstName: 'Shedrack', surname: 'Akintayo'}) }, [])//pass in an empty array as a second argument return( <div> <h1>Title: {title}</h1> <h3>Name: {name.firstName}</h3> <h3>Surname: {name.surname}</h3> </div> ); }; export default App

Nous avons maintenant importé le crochet useEffect et avons également utilisé la fonction useEffect() pour définir l'état de notre propriété name et surname, ce qui est assez net et concis.

Vous avez peut-être remarqué le hook useEffect dans le deuxième argument qui est un tableau vide ; c'est parce qu'il contient un appel à setFullName qui n'a pas de liste de dépendances. Le passage du deuxième argument empêchera une chaîne infinie de mises à jour ( componentDidUpdate() ) et permettra également à notre useEffect() d'agir comme une méthode de cycle de vie componentDidMount et de s'afficher une fois sans restituer à chaque modification de l'arborescence.

Notre application React devrait maintenant ressembler à ceci :

Réagissez à l'aide du crochet useEffect ( Grand aperçu )

Nous pouvons également modifier la propriété title de notre application dans la fonction useEffect() en appelant la fonction setTitle() , comme ceci :

 import React, {useState, useEffect} from 'react'; function App() { //Define State const [name, setName] = useState({firstName: 'name', surname: 'surname'}); const [title, setTitle] = useState('BIO'); //Call the use effect hook useEffect(() => { setName({firstName: 'Shedrack', surname: 'Akintayo'}) setTitle({'My Full Name'}) //Set Title }, [])// pass in an empty array as a second argument return( <div> <h1>Title: {title}</h1> <h3>Name: {name.firstName}</h3> <h3>Surname: {name.surname}</h3> </div> ); }; export default App

Maintenant, après que notre application a été restituée, elle affiche maintenant le nouveau titre.

Notre projet fini ( Grand aperçu )

useContext()

Le crochet useContext() accepte un objet de contexte, c'est-à-dire la valeur renvoyée par React.createContext , puis il renvoie la valeur de contexte actuelle pour ce contexte.

Ce crochet donne aux composants fonctionnels un accès facile au contexte de votre application React. Avant l'introduction du crochet useContext , vous deviez configurer un contextType ou un <Consumer> pour accéder à votre état global transmis par un fournisseur dans un composant de classe.

Fondamentalement, le crochet useContext fonctionne avec l'API React Context, qui est un moyen de partager des données en profondeur dans votre application sans avoir à transmettre manuellement les accessoires de votre application à différents niveaux. Désormais, useContext() facilite un peu l'utilisation de Context.

Les extraits de code ci-dessous montreront comment fonctionne l'API Context et comment le useContext l'améliore.

La manière normale d'utiliser l'API de contexte

 import React from "react"; import ReactDOM from "react-dom"; const NumberContext = React.createContext(); function App() { return ( <NumberContext.Provider value={45}> <div> <Display /> </div> </NumberContext.Provider> ); } function Display() { return ( <NumberContext.Consumer> {value => <div>The answer to the question is {value}.</div>} </NumberContext.Consumer> ); } ReactDOM.render(<App />, document.querySelector("#root"));

Décomposons maintenant l'extrait de code et expliquons chaque concept.

Ci-dessous, nous créons un contexte appelé NumberContext . Il est destiné à renvoyer un objet avec deux valeurs : { Provider, Consumer } .

 const NumberContext = React.createContext();

Ensuite, nous utilisons la valeur Provider renvoyée par le NumberContext que nous avons créé pour rendre une valeur particulière disponible pour tous les enfants.

 function App() { return ( <NumberContext.Provider value={45}> <div> <Display /> </div> </NumberContext.Provider> ); }

Avec cela, nous pouvons utiliser la valeur Consumer renvoyée par le NumberContext que nous avons créé pour obtenir la valeur que nous avons mise à la disposition de tous les enfants. Si vous avez remarqué, ce composant n'a pas reçu d'accessoires.

 function Display() { return ( <NumberContext.Consumer> {value => <div>The answer to the question is {value}.</div>} </NumberContext.Consumer> ); } ReactDOM.render(<App />, document.querySelector("#root"));

Notez comment nous avons pu obtenir la valeur du composant App dans le composant Display en enveloppant notre contenu dans un NumberContext.Consumer et en utilisant la méthode render props pour récupérer la valeur et la restituer.

Tout fonctionne bien et la méthode d'accessoires de rendu que nous avons utilisée est un très bon modèle pour gérer les données dynamiques, mais à long terme, cela introduit une imbrication et une confusion inutiles si vous n'y êtes pas habitué.

Utilisation de la méthode useContext

Pour expliquer la méthode useContext , nous allons réécrire le composant Display en utilisant le crochet useContext.

 // import useContext (or we could write React.useContext) import React, { useContext } from 'react'; // old code goes here function Display() { const value = useContext(NumberContext); return <div>The answer is {value}.</div>; }

C'est tout ce que nous devons faire pour afficher notre valeur. Plutôt chouette, non ? Vous appelez le crochet useContext() et passez dans l'objet de contexte que nous avons créé et nous en récupérons la valeur.

Remarque : N'oubliez pas que l'argument transmis au crochet useContext doit être l'objet de contexte lui-même et tout composant appelant useContext sera toujours restitué lorsque la valeur de contexte change.

useReducer()

Le crochet useReducer est utilisé pour gérer les états complexes et les transitions d'état. Il prend en compte une fonction de reducer et également une entrée d'état initial ; ensuite, il renvoie l'état actuel ainsi qu'une fonction de dispatch en sortie au moyen de la déstructuration du tableau.

Le code ci-dessous est la syntaxe appropriée pour utiliser le crochet useReducer .

 const [state, dispatch] = useReducer(reducer, initialArg, init);

C'est une sorte d'alternative au hook useState ; il est généralement préférable d' useState lorsque vous avez une logique d'état complexe qui concerne plusieurs sous-valeurs ou lorsque l'état suivant dépend du précédent.

Autres crochets React disponibles

useCallback Ce crochet renvoie une fonction de rappel qui est mémorisée et qui ne change que si une dépendance dans l'arborescence des dépendances change.
useMemo Ce crochet renvoie une valeur mémorisée, vous pouvez passer une fonction "create" et également un tableau de dépendances. La valeur renvoyée n'utilisera à nouveau la valeur mémorisée que si l'une des dépendances de l'arborescence des dépendances change.
useRef Ce crochet renvoie un objet ref mutable dont la propriété .current est initialisée à l'argument passé ( initialValue ). L'objet renvoyé sera disponible pendant toute la durée de vie du composant.
useImperativeHandle Ce hook est utilisé pour personnaliser la valeur d'instance qui est rendue disponible pour les composants parents lors de l'utilisation de refs dans React.
useLayoutEffect Ce hook est similaire au hook useEffect , cependant, il se déclenche de manière synchrone après toutes les mutations DOM. Il s'affiche également de la même manière que componentDidUpdate et componentDidMount .
useDebugValue Ce crochet peut être utilisé pour afficher une étiquette pour les crochets personnalisés dans React Dev Tools. Il est très utile pour le débogage avec les outils de développement React.

Crochets de réaction personnalisés

Un "Hook personnalisé" est une fonction JavaScript dont les noms sont précédés du mot use et peuvent être utilisés pour appeler d'autres Hooks. Il vous permet également d'extraire la logique des composants dans des fonctions réutilisables ; ce sont des fonctions JavaScript normales qui peuvent utiliser d'autres crochets à l'intérieur de celui-ci, et contiennent également une logique avec état commune qui peut être utilisée dans plusieurs composants.

Les extraits de code ci-dessous illustrent un exemple de React Hook personnalisé pour implémenter le défilement infini (par Paulo Levy) :

 import { useState } from "react"; export const useInfiniteScroll = (start = 30, pace = 10) => { const [limit, setLimit] = useState(start); window.onscroll = () => { if ( window.innerHeight + document.documentElement.scrollTop === document.documentElement.offsetHeight ) { setLimit(limit + pace); } }; return limit; };

Ce Hook personnalisé accepte deux arguments qui sont start et pace . L'argument start est le nombre initial d'éléments à rendre tandis que l'argument pace est le nombre suivant d'éléments à rendre. Par défaut, les arguments start et pace sont définis sur 30 et 10 respectivement, ce qui signifie que vous pouvez réellement appeler le crochet sans aucun argument et que ces valeurs par défaut seront utilisées à la place.

Donc, pour utiliser ce crochet dans une application React, nous l'utiliserions avec une API en ligne qui renvoie de "fausses" données :

 import React, { useState, useEffect } from "react"; import { useInfiniteScroll } from "./useInfiniteScroll"; const App = () => { let infiniteScroll = useInfiniteScroll(); const [tableContent, setTableContent] = useState([]); useEffect(() => { fetch("https://jsonplaceholder.typicode.com/todos/") .then(response => response.json()) .then(json => setTableContent(json)); }, []); return ( <div style={{ textAlign: "center" }}> <table> <thead> <tr> <th>User ID</th> <th>Title</th> </tr> </thead> <tbody> {tableContent.slice(0, infiniteScroll).map(content => { return ( <tr key={content.id}> <td style={{ paddingTop: "10px" }}>{content.userId}</td> <td style={{ paddingTop: "10px" }}>{content.title}</td> </tr> ); })} </tbody> </table> </div> ); }; export default App;

Le code ci-dessus affichera une liste de fausses données ( userID et title ) qui utilisent le crochet de défilement infini pour afficher le nombre initial de données à l'écran.

Conclusion

J'espère que vous avez aimé travailler à travers ce tutoriel. Vous pouvez toujours en savoir plus sur React Hooks à partir des références ci-dessous.

Si vous avez des questions, vous pouvez les laisser dans la section des commentaires et je me ferai un plaisir de répondre à chacune d'entre elles !

Le référentiel de support pour cet article est disponible sur Github.

Ressources et lectures complémentaires

  • « Référence de l'API Hooks », documentation React.js
  • "Que sont les crochets React ?", Robin Wieruch
  • "Comment fonctionne le crochet useContext ", Dave Ceddia
  • "React Hooks: Comment utiliser useEffect() ", Hossein Ahmadi, Medium
  • "Écrire vos propres crochets de réaction personnalisés", Aayush Jaiswal, moyen
  • "Recettes de crochets faciles à comprendre", Gabe Ragland, useHooks ()