Fermer

mars 26, 2024

7 erreurs courantes lors de l’utilisation de React Hooks

7 erreurs courantes lors de l’utilisation de React Hooks


Une mauvaise utilisation de React Hooks peut entraîner des problèmes de performances et des bugs. Apprenez de certaines erreurs courantes commises par les développeurs avec React Hooks et des solutions pour les éviter au mieux.

Les React Hooks ont révolutionné l’écosystème React depuis leur création dans React 16.8. Ils offrent la possibilité d’exploiter les fonctionnalités d’état et de cycle de vie au sein des composants fonctionnels, ce qui n’était auparavant possible que dans les composants de classe.

Plus tôt, nous avons écrit quelques plongées approfondies dans certains des principaux React Hooks comme le utiliserEffet, utiliserContext et utiliserRéducteur crochets.

Malgré l’utilité et l’utilité que React Hooks nous offre, une utilisation inappropriée peut entraîner une dégradation des performances et des bugs insaisissables. Dans cet article, nous présenterons quelques erreurs courantes commises par les développeurs lors de l’utilisation de React Hooks et des solutions pour les éviter au mieux.

1. Utiliser des hooks dans des instructions conditionnelles

C’est une erreur courante d’utiliser des hooks dans des boucles, des instructions conditionnelles ou des fonctions imbriquées. Cela peut conduire à des appels de hook incohérents entre les rendus, entraînant des comportements erratiques et des bugs difficiles à trouver.

Utilisation incorrecte

function Component() {
  if (condition) {
    const [state, setState] = useState(initialState);
  }
  
}

Les hooks doivent toujours être invoqués dans le même ordre lors de chaque rendu de composant. Cela contribue à favoriser un comportement des composants plus prévisible et plus stable.

usage correct

function Component() {
  const [state, setState] = useState(initialState);
  if (condition) {
    
  }
  
}

2. État abusif

Une dépendance excessive à l’égard de l’État est un autre écueil fréquent. Toutes les variables d’un composant ne doivent pas nécessairement faire partie de l’état du composant, surtout si elles ne déclenchent pas de nouveau rendu. En faisant la distinction entre les données avec état et sans état, nous pouvons optimiser les performances de notre composant en réduisant les rendus inutiles.


const [value, setValue] = useState("");


let value = "";

3. État en mutation directe

L’état de réaction est intrinsèquement immuableet la mutation directe est une erreur parfois commise par les développeurs.

Utilisation incorrecte

const [state, setState] = useState([]);
state.push("new item"); 

La mutation d’état directe ne déclenche pas immédiatement un nouveau rendu, provoquant une différence entre l’état affiché et l’état réel du composant.

Au lieu de cela, nous devrions toujours utiliser la fonction de mise à jour d’état disponible à partir du useState hook pour mettre à jour l’état. Lorsque l’état change de cette façon, cela déclenche un nouveau rendu nécessaire qui garantit la cohérence entre l’état réel du composant et sa sortie rendue.

const [state, setState] = useState([]);
setState((prevState) => [...prevState, "new item"]); 

4. Utilisation de données d’état obsolètes

Un piège courant lors de l’utilisation de React Hooks est l’utilisation abusive de données d’état obsolètes. Cela peut se produire lorsque nous référençons directement la variable d’état dans des mises à jour d’état consécutives. Étant donné que les mises à jour d’état peuvent être asynchrones, la variable d’état peut ne pas refléter la dernière valeur lorsqu’elle est référencée lors d’appels successifs.

Utilisation incorrecte

const [count, setCount] = useState(0);

setCount(count + 1);
setCount(count + 1); 

Dans l’usage incorrect ci-dessus, count est référencé directement dans chaque setCount() appel. Si ces mises à jour d’état sont groupées (comme c’est souvent le cas dans les gestionnaires d’événements et les méthodes de cycle de vie), alors les deux appels à setCount() utilisera la même valeur initiale de countconduisant à un état final incorrect.

Au lieu de cela, nous pouvons utiliser la forme de fonction de mise à jour de setCount(), qui garantit que chaque mise à jour est basée sur le dernier état. La fonction de mise à jour prend l’état précédent comme argument et renvoie le nouvel état, de sorte que chaque mise à jour consécutive aura la valeur correcte, évitant ainsi les problèmes de données d’état obsolètes.

usage correct

const [count, setCount] = useState(0);

setCount((prevCount) => prevCount + 1);
setCount((prevCount) => prevCount + 1); 

5. Exécuter un effet pour chaque mise à jour

Le useEffect le hook est souvent utilisé à mauvais escient pour s’exécuter à chaque mise à jour de composant. Bien que cela soit nécessaire dans certains scénarios, nous n’avons souvent besoin d’exécuter un effet qu’une seule fois lors du montage ou lorsque des dépendances spécifiques changent.

Utilisation incorrecte

useEffect(() => {
  fetch("https://example.com/api").then();
}); 

Dans l’exemple ci-dessus, l’exécution de l’effet à chaque rendu entraînera de nombreux appels d’API pouvant entraîner une dégradation des performances et un état incohérent.

En fournissant un tableau de dépendances vide, nous pouvons garantir que l’effet ne s’exécute qu’une seule fois lors du montage, comme dans le cas traditionnel. componentDidMount méthode de cycle de vie dans les composants de classe.

usage correct

useEffect(() => {
  fetch("https://example.com/api").then();
}, []); 

5. Ne pas éliminer les effets secondaires

Les effets secondaires sont des opérations qui interagissent avec l’extérieur du périmètre d’une fonction, affectant l’environnement externe. Cela pourrait impliquer la récupération de données, les abonnements, les manipulations manuelles du DOM et les minuteries comme setTimeout et setInterval.

Ne pas éliminer les effets secondaires dans le useEffect Le hook est une autre erreur courante qui peut survenir et entraîner un comportement inattendu et/ou des fuites de mémoire.

Utilisation incorrecte

useEffect(() => {
  const timer = setTimeout(() => {
    
  }, 1000);
  
});

En renvoyant une fonction de nettoyage de notre effet, nous pouvons supprimer les effets secondaires avant le composant se démonte ou avant que l’effet ne s’exécute à nouveau, évitant ainsi les fuites de mémoire.

usage correct

useEffect(() => {
  const timer = setTimeout(() => {
    
  }, 1000);

  
  return () => {
    clearTimeout(timer);
  };
});

6. Omettre les dépendances dans le tableau de dépendances

Une erreur courante consiste à négliger d’inclure les dépendances dans le tableau de dépendances de useEffect, useCallback ou useMemo crochets. Si une variable de la portée du composant est utilisée dans les rappels de ces hooks, elle doit souvent être incluse dans le tableau de dépendances.

Utilisation incorrecte

function Component({ prop }) {
  useEffect(() => {
    console.log(prop);
  }, []); 
  
}

L’omission des dépendances peut conduire à la capture de variables obsolètes qui peuvent avoir changé depuis la dernière exécution de l’effet, ce qui peut conduire à un comportement imprévisible.

usage correct

function Component({ prop }) {
  useEffect(() => {
    console.log(prop);
  }, [prop]); 
  
}

En déclarant correctement toutes les dépendances, nous garantissons que le hook se met à jour chaque fois qu’une dépendance change. Cela se traduit par un comportement cohérent et attendu.

7. Oublier de mémoriser les appels de fonction coûteux

La mémorisation est une technique d’optimisation qui accélère principalement les applications en stockant les résultats d’appels de fonctions coûteux et en réutilisant le résultat mis en cache lorsque les mêmes entrées se reproduisent. Cette technique est incroyablement utile pour les fonctions qui nécessitent beaucoup de calculs et sont fréquemment appelées avec les mêmes arguments.

React fournit deux hooks, useMemo et useCallbackqui implémentent la mémorisation. useMemo est utilisé pour mémoriser la valeur de retour d’une fonction, tandis que useCallback est utilisé pour mémoriser l’instance de la fonction elle-même.

Si des fonctions coûteuses ne sont pas correctement mémorisées, elles peuvent provoquer des rendus inutiles. Dans l’exemple suivant, si le composant parent effectue un nouveau rendu pour une raison quelconque, expensiveFunction() sera recréé. Cela entraînera des rendus inutiles dans le composant enfant, car il recevra un nouvel accessoire à chaque fois, que le résultat réel du calcul ait changé ou non.

Utilisation incorrecte

function Component({ prop }) {
  const expensiveFunction = () => {
    
  };

  return <ChildComponent func={expensiveFunction} />;
}

usage correct

Nous pouvons optimiser cela en utilisant le useCallback crochet:

function Component({ prop }) {
  const expensiveFunction = useCallback(
    () => {
      
    },
    [
      
    ]
  );

  return <OtherComponent func={expensiveFunction} />;
}

Dans cet usage correct, le useCallback le crochet garantit que expensiveFunction() n’est recréé que lorsque ses dépendances changent. Cela signifie que le composant enfant ne sera restitué que lorsque la valeur calculée change, évitant ainsi les rerendus inutiles et améliorant les performances de l’application React.

Conclure

Les React Hooks ont considérablement transformé le paysage React en permettant l’utilisation de fonctionnalités d’état et de cycle de vie dans les composants fonctionnels. Cependant, ils peuvent également présenter des défis uniques.

Des erreurs telles que l’utilisation de hooks dans des instructions conditionnelles, la surutilisation de l’état, la mutation directe de l’état, l’utilisation abusive de données d’état obsolètes, etc. peuvent conduire à un code inefficace et à des bogues difficiles à retracer. En évitant ces erreurs courantes et en suivant les meilleures pratiques, les développeurs peuvent exploiter pleinement le potentiel de React Hooks, conduisant à des applications React plus performantes, stables et maintenables.




Source link