Fermer

mars 14, 2019

Comment démarrer et créer le vôtre –


Les crochets React sont des fonctions spéciales qui vous permettent de vous «accrocher» aux fonctions React. Par exemple, le hook useState vous permet d'ajouter l'état React à un composant fonctionnel. useEffect est un autre crochet qui vous permet d'effectuer des effets secondaires dans des composants fonctionnels. Les effets secondaires sont généralement mis en œuvre à l'aide de méthodes de cycle de vie. Avec les hooks, cela n'est plus nécessaire.

Cela signifie que vous n'avez plus besoin de définir une classe lors de la construction d'un composant React. Il s’avère que l’architecture de classe utilisée dans React est à l’origine de nombreux défis auxquels les développeurs de React sont confrontés au quotidien. Nous sommes souvent en train d’écrire de gros composants complexes difficiles à décomposer. Le code associé est réparti sur plusieurs méthodes de cycle de vie, ce qui devient difficile à lire, à maintenir et à tester. De plus, nous devons utiliser le mot clé this pour accéder à l'état, aux accessoires et aux fonctions. Nous devons également lier les fonctions à ce pour qu'elles soient accessibles au sein du composant. Ensuite, nous rencontrons le problème de forage excessif – appelé aussi wrapper hell – lorsqu'il s'agit de composants d'ordre supérieur.

En un mot, les crochets sont une fonctionnalité révolutionnaire qui simplifiera efficacement votre code, en facilitant la lecture, la maintenance et le test. en vase clos et réutilisé dans vos projets. Cela ne vous prendra qu'une heure pour apprendre. Bientôt, vous commencerez à penser très différemment à la manière dont vous écrivez le code React.

React Hooks a été annoncé pour la première fois lors d'une conférence React qui s'est tenue en octobre 2018. Il a été officiellement mis à disposition sous React 16.8 le mois dernier. Cette fonctionnalité est encore en développement. Un certain nombre de fonctionnalités de la classe React sont encore en cours de migration dans les hooks. La bonne nouvelle est que vous pouvez commencer à les utiliser maintenant. Vous pouvez toujours utiliser les composants de la classe React si vous le souhaitez – cependant, je doute que vous le fassiez après avoir terminé ce guide d'introduction.

Si j'ai attiré votre curiosité, plongeons-y et voyons quelques exemples pratiques.

Conditions préalables [19659007] Cet article est destiné aux développeurs React intermédiaires à avancés. Si vous êtes débutant, veuillez commencer par suivre les didacticiels suivants:

Je ne vous expliquerai pas comment créer un nouveau projet React ou d’autres compétences de niveau débutant. Vous devriez pouvoir suivre ce guide facilement. Vous pouvez accéder au projet terminé sur GitHub .

useState Hook

Considérez le composant de classe React suivant:

 import React from "react";

classe d'exportation par défaut ClassDemo étend React.Component {
  constructeur (accessoires) {
    super (accessoires);
    this.state = {
      nom: "Agata"
    };
    this.handleNameChange = this.handleNameChange.bind (this);
  }

  handleNameChange (e) {
    this.setState ({
      nom: e.target.value
    });
  }

  render () {
    revenir (
      

Bonjour {this.state.name}

);   } }

Voici à quoi cela ressemble:

 Nom de classe des crochets à réaction

Lorsque vous mettez à jour le champ du nom, le message "Hello *" doit également être mis à jour. Donnez-vous une minute pour comprendre le code. Ensuite, nous allons écrire une nouvelle version de ce code en utilisant un crochet à réaction appelé useState .

Sa syntaxe est la suivante:

 const [state, setState] = useState (initialState);

Lorsque vous appelez la fonction useState elle renvoie deux éléments:

  • state – le nom de votre état, par exemple. this.state.name ou this.state.location
  • setState – une fonction permettant de définir une nouvelle valeur pour votre état. Semblable à this.setState ({name: newValue})

L'initialisation initialeState est la valeur par défaut que vous attribuez à votre nouvel état lors de la phase de déclaration d'état. Maintenant que vous avez une idée de ce que useState est, mettons-le en action.

 import React, {useState} from "react";

fonction par défaut d'exportation HookDemo (props) {
  const [name, setName] = useState ("Agata");

  fonction handleNameChange (e) {
    setName (e.target.value);
  }

  revenir (
    

Bonjour {nom}

); }

Prenez note des différences entre cette version et la version de classe. C’est déjà beaucoup plus compact et plus facile à comprendre que la version classique, mais ils font tous les deux exactement la même chose. Examinons les différences:

  • Le constructeur de la classe entière a été remplacé par le crochet useState qui consiste en une seule ligne.
  • Parce que le useState Hook renvoie local. vous n'avez plus besoin du mot-clé this pour référencer vos variables de fonction ou d'état. Honnêtement, c’est un problème majeur pour la plupart des développeurs JavaScript, car il n’est pas toujours clair de savoir quand utiliser ce .
  • Le code JSX est maintenant plus propre, car vous pouvez référencer les valeurs de l’état local sans utiliser this .state .

J'espère que vous êtes maintenant impressionné! Vous vous demandez peut-être quoi faire lorsque vous avez besoin de déclarer plusieurs valeurs d'état. La réponse est simple: il suffit d'appeler un autre point d'ancrage useState . Vous pouvez déclarer autant de fois que vous le souhaitez, à condition de ne pas compliquer excessivement votre composant.

Assurez-vous de le faire en haut, et jamais dans une condition. Voici un exemple de composant avec plusieurs useState Hooks:

 import React, {useState} from "react";

fonction par défaut d'exportation HookDemo (props) {
  const [name, setName] = useState ("Agata");
  const [location, setLocation] = useState ("Nairobi");

  fonction handleNameChange (e) {
    setName (e.target.value);
  }

  fonction handleLocationChange (e) {
    setLocation (e.target.value);
  }

  revenir (
    

Bonjour {nom} du {lieu}       

); }

Assez simple, n’est-ce pas? Faire la même chose dans la version Class exigerait que vous utilisiez encore plus de ces mots-clés . Passons au prochain crochet de réaction de base.

useEffect Crochet

La ​​plupart des composants de React sont nécessaires pour effectuer une opération spécifique telle que la récupération de données, la souscription ou la modification manuelle du DOM. Ces types d'opérations sont connus sous le nom d'effets secondaires.

Nous plaçons généralement notre code pour les effets secondaires dans de composantDidMount et de composantDidUpdate . Ce sont des méthodes de cycle de vie qui nous permettent de déclencher la méthode de rendu au bon moment.

Voici un exemple simple:

 composantDidMount () {
  document.title = this.state.name + "from" + this.state.location;
}

Ce code va simplement définir le titre du document. Toutefois, lorsque vous essayez de modifier les valeurs d'état via le formulaire, rien ne se produit. Pour résoudre ce problème, vous devez ajouter une autre méthode de cycle de vie:

 componentDidUpdate () {
    document.title = this.state.name + "from" + this.state.location;
  }

La mise à jour du formulaire devrait également mettre à jour le titre du document.

 Titre de la classe des crochets à réaction

Voyons comment mettre en œuvre la même logique en utilisant le useEffect Hook :

 import React, {useState, useEffect} depuis "react";
// ...

useEffect (() => {
  document.title = name + "from" + location;
});

Avec ces quelques lignes de code, nous avons implémenté le travail de deux méthodes de cycle de vie dans une fonction simple.

Cet exemple est simple. Cependant, dans certains cas, vous devez écrire du code de nettoyage, tel que la désinscription d'un flux de données ou la désinscription d'un écouteur d'événement. Voyons un exemple de la façon dont cela est normalement implémenté dans un composant de la classe React:

 // ...
  constructeur (accessoires) {
    super (accessoires);
    this.state = {
      nom: "Agata",
      lieu: "Nairobi",
      résolution: {
        largeur: window.innerWidth,
        hauteur: window.innerHeight
      }
    };
    // ...
    this.handleResize = this.handleResize.bind (this);
  }

  composantDidMount () {
    document.title = this.state.name + "from" + this.state.location;
    window.addEventListener ("resize", this.handleResize);
  }

  composantDidUpdate () {
    document.title = this.state.name + "from" + this.state.location;
    window.addEventListener ("resize", this.handleResize);
  }
  // ...
   handleResize () {
    this.setState ({
      résolution: {
        largeur: window.innerWidth,
        hauteur: window.innerHeight
      }
    });
  }

  render () {
    revenir (
      
        ...         

          {this.state.resolution.width} x {this.state.resolution.height}         

)   }

L'ajout du code ci-dessus affichera la résolution actuelle de la fenêtre de votre navigateur. Redimensionnez la fenêtre et vous devriez voir les numéros se mettre à jour automatiquement. Si vous appuyez sur F11 sous Chrome, la résolution complète de votre moniteur devrait s’afficher.

 Résolution du crochet de réaction React

Reproduisons le code «classe» ci-dessus dans notre version «crochet». Nous devrons définir une troisième fonction useState et une deuxième fonction useEffect pour gérer cette nouvelle fonctionnalité:

 // ... déclaration d'état
const [resolution, setResolution] = useState ({
  largeur: window.innerWidth,
  hauteur: window.innerHeight
});
// ...
useEffect (() => {
  const handleResize = () => {
    setResolution ({
      largeur: window.innerWidth,
      hauteur: window.innerHeight
    });
  };
  window.addEventListener ("resize", handleResize);
  return () => {
    window.removeEventListener ("resize", handleResize);
  };
});
// ... rendu jsx

  {résolution.width} x {resolution.height}

;

Étonnamment, cette version avec crochet du code fait exactement la même chose. C’est plus propre et plus compact. L'avantage d'insérer du code dans sa propre déclaration useEffect est que nous pouvons facilement le tester, car le code est isolé.

Avez-vous remarqué que nous retournons une fonction dans cette useEffect crochet? En effet, toute fonction que vous renvoyez dans une fonction useEffect sera considérée comme le code de nettoyage. Si vous ne renvoyez pas de fonction, aucun nettoyage ne sera effectué. Dans ce cas, un nettoyage sera nécessaire, sinon vous rencontrerez un bogue lors de l'exécution du code.

Custom React Hooks

Maintenant que vous avez appris l'existence de useState et useEffect Hooks, laissez-moi vous montrer une façon vraiment cool de rendre votre code encore plus compact, plus propre et réutilisable que ce que nous avons réalisé jusqu'à présent. Nous allons créer un crochet personnalisé pour simplifier encore plus notre code.

Nous le ferons en extrayant le crochet à effet resize et en le plaçant en dehors de notre composant. Créez simplement une nouvelle fonction comme suit:

 function useWindowResolution () {
  const [resolution, setResolution] = useState ({
    largeur: window.innerWidth,
    hauteur: window.innerHeight
  });
  useEffect (() => {
    const handleResize = () => {
      setResolution ({
        largeur: window.innerWidth,
        hauteur: window.innerHeight
      });
    };
    window.addEventListener ("resize", handleResize);
    return () => {
      window.removeEventListener ("resize", handleResize);
      console.log ("nettoyage");
    };
  });
  résolution de retour;
}

Ensuite, vous devrez remplacer ce code:

 const [resolution, setResolution] = useState ({
  largeur: window.innerWidth,
  hauteur: window.innerHeight
});

… avec ceci:

 const resolution = useWindowResolution ();

Supprimer le deuxième code useEffect . Enregistrez votre fichier et testez-le. Redimensionner la fenêtre du navigateur devrait effectivement mettre à jour les chiffres de résolution. Si vous rencontrez un certain décalage, remplacez la fonction useWindowResolution par celle-ci:

 function useWindowResolution () {
  const [width, setWidth] = useState (window.innerWidth);
  const [height, setHeight] = useState (window.innerHeight);
  useEffect (() => {
    const handleResize = () => {
      setWidth (window.innerWidth);
      setHeight (window.innerHeight);
    };
    window.addEventListener ("resize", handleResize);
    return () => {
      window.removeEventListener ("resize", handleResize);
    };
  }, [width, height]);
  revenir {
    largeur,
    la taille
  };
}

Il semble qu'il y ait un bug qui cause un retard dans le code de nettoyage. L'utilisation de primitives pour l'état local résout ce problème. Au moment où vous lisez ceci, il est possible que vous ne rencontriez pas ce problème.

Maintenant que nous avons créé notre premier hook personnalisé, procédons de la même manière pour le titre du document. Vous devrez identifier vous-même le code pertinent à remplacer. Je vais simplement vous montrer le code du crochet personnalisé:

 // ...
résolution const = useWindowResolution ();
useDocumentTitle (name + "from" + location);
// ...

function useDocumentTitle (title) {
  useEffect (() => {
    document.title = title;
  });
}

Le titre du document devrait changer comme avant. Maintenant, refactorisons les champs de formulaire. Le composant refactoré ressemblera à ceci:

 fonction par défaut d'exportation HookDemo (props) {
  nom de const = useFormInput ("Agata");
  const location = useFormInput ("Nairobi");
  résolution const = useWindowResolution ();
  useDocumentTitle (name.value + "from" + location.value);

  revenir (
    

Bonjour {name.value} à partir de {location.value}       

{résolution.width} x {résolution.height}       

); } function useFormInput (initialValue) {   const [value, setValue] = useState (initialValue);   fonction handleChange (e) {     setValue (e.target.value);   }   revenir {     valeur,     onChange: handleChange   }; }

Parcourez le code lentement et identifiez tous les changements que nous avons apportés. Plutôt chouette, non? Notre composant est beaucoup plus compact. Nous pouvons empaqueter useFormInput useDocumentTitle et useWindowResolution dans un module npm externe car ils sont complètement indépendants de la logique principale. Nous pouvons facilement réutiliser ces hooks personnalisés dans d'autres parties du projet, voire dans d'autres projets à l'avenir.

Pour référence, voici la version complète du composant hooks:

 import React, {useState, useEffect} from "rea ";

fonction par défaut d'exportation HookDemo (props) {
  nom de const = useFormInput ("Agata");
  const location = useFormInput ("Nairobi");
  résolution const = useWindowResolution ();
  useDocumentTitle (name.value + "from" + location.value);

  revenir (
    

Bonjour {name.value} à partir de {location.value}       

{résolution.width} x {résolution.height}       

); } function useDocumentTitle (title) {   useEffect (() => {     document.title = title;   }); } function useFormInput (initialValue) {   const [value, setValue] = useState (initialValue);   fonction handleChange (e) {     setValue (e.target.value);   }   revenir {     valeur,     onChange: handleChange   }; } function useWindowResolution () {   const [width, setWidth] = useState (window.innerWidth);   const [height, setHeight] = useState (window.innerHeight);   useEffect (() => {     const handleResize = () => {       setWidth (window.innerWidth);       setHeight (window.innerHeight);     };     window.addEventListener ("resize", handleResize);     return () => {       window.removeEventListener ("resize", handleResize, true);     };   }, [width, height]);   revenir {     largeur,     la taille   }; }

Le composant du hook devrait se comporter et se comporter exactement comme la version du composant de classe:

 React Hooks Final

Si vous le comparez à la version du composant de classe, vous vous rendrez compte que la fonctionnalité de hook réduit votre code composant d'au moins 30%. Vous pouvez même réduire davantage votre code en exportant les fonctions réutilisables vers une bibliothèque npm

C’est la fin de notre guide d’introduction, mais il ya tellement de choses sur les hooks que je n’ai pas abordés. Nous vous donnerons des indications pour votre propre exploration dans la section suivante.

Crochets React officiels

Voici les crochets React de base que vous utiliserez certainement dans chaque projet React:

  • . ] - pour la gestion de l’état local
  • useEffects - remplace les fonctions de cycle de vie
  • useContext - vous permet de travailler facilement avec l’API Contexte de vie (résout le problème du perçage des supports) [19659032] Nous disposons également de crochets de réaction officiels supplémentaires que vous pouvez utiliser en fonction des exigences de votre projet:

    • useReducer - Une version avancée de useState pour la gestion de la logique d’état complexe. C’est assez similaire à Redux
    • . UseCallback - Renvoie une fonction qui renvoie une valeur pouvant être mise en cache. Utile pour l'optimisation des performances si vous souhaitez éviter les rediffusions inutiles lorsque l'entrée n'a pas été modifiée.
    • useMemo - Renvoie une valeur à partir d'une fonction memoized . Semblable à calculé si vous connaissez bien Vue.
    • useRef - Retourne un objet ref mutable qui persiste pendant toute la durée de vie du composant.
    • useImperativeHandle - personnalise la valeur d'instance exposée aux composants parent lors de l'utilisation de ref .
    • useLayoutEffect - Semblable à useEffect mais se déclenche de manière synchronisée après tout
    • useDebugValue - Affiche une étiquette pour les crochets personnalisés dans React DevTools.

    Certains de ces crochets supplémentaires sont un peu avancés et nécessitent des didacticiels distincts.

    Résumé

    La communauté React a réagi positivement à la nouvelle fonctionnalité React Hooks. Il existe déjà un référentiel open-source appelé awesome-react-hooks . Des centaines de crochets réactifs personnalisés ont été soumis à ce référentiel. Voici un exemple rapide de l'un de ces points d'ancrage pour stocker des valeurs dans la mémoire de stockage locale:

     import useLocalStorage à partir de "@ rehooks / local-storage";
    
    function MyComponent () {
      let name = useLocalStorage ("name"); // envoie la clé à suivre.
      revenir (
        

    {name}

    ); }

    Vous devez installer le crochet de stockage local avec npm ou un fil similaire pour l'utiliser:

     le fil add @ rehooks / local-storage
    

    Très chouette, non? L'introduction de React Hooks a fait sensation. Ses ondes ont dépassé la communauté React pour entrer dans le monde JavaScript. En effet, les crochets constituent un nouveau concept pouvant profiter à tout l'écosystème JavaScript. En fait, l'équipe de Vue.js a déjà commencé à mettre en œuvre sa propre version.

    Il est également question de React Hooks et de l'API de contexte qui renversent Redux de son trône de gestion d'état. Clairement, les crochets ont rendu le codage beaucoup plus simple et ont changé la façon dont nous allons écrire le nouveau code. Si vous êtes comme moi, vous avez probablement très envie de réécrire toutes vos classes de composants React et de les remplacer par des hooks de composants fonctionnels.

    Notez que cela n’est pas vraiment nécessaire: l’équipe React ne prévoit pas de déprécier les composants de la classe React. Vous devez également savoir que toutes les méthodes de cycle de vie de la classe React ne sont pas encore possibles avec les points d'ancrage. Vous devrez peut-être vous en tenir aux classes de composants React un peu plus longtemps.

    Si vous vous sentez suffisamment à l'aise avec vos nouvelles connaissances des crochets React de base, j'aimerais vous lancer un défi. Refactoriser cette classe de compte à rebours en utilisant les crochets React pour le rendre aussi propre et compact que possible. Bonne codification!




Source link