React: eslint-plugin-react-hooks: erreur 'Hook est appelé conditionnellement' en dehors de la condition

Créé le 19 sept. 2019  ·  4Commentaires  ·  Source: facebook/react

Voulez-vous demander une fonctionnalité ou signaler un bogue ?

BUG (éventuellement)

Quel est le comportement actuel?

Le plugin affiche cette erreur:

React Hook "useState" est appelé conditionnellement. Les hooks de réaction doivent être appelés exactement dans le même ordre dans chaque rendu de composant. Avez-vous accidentellement appelé un React Hook après un retour anticipé? (react-hooks / rules-of-hooks) eslint

Mais je ne pense pas que j'appelle des hooks de manière conditionnelle.

Le code:

https://codesandbox.io/s/exciting-bhabha-mqj7q

function App(props) {
  const someObject = { propA: true, propB: false };

  for (const propName in someObject) {
    if (propName === true) {
      console.log("something");
    } else {
      console.log("whatever");
    }
  }

  // THE PLUGIN ERROR MSG ON THIS useState
  const [myState, setMyState] = useState(null);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

image

Quel est le comportement attendu?

Le plugin n'afficherait pas l'erreur dans cette situation.

Quelles versions de React et quel navigateur / système d'exploitation sont concernés par ce problème?

image

ESLint Rules Bug

Commentaire le plus utile

Tous les 4 commentaires

J'ai remarqué que pour cet exemple particulier:

pathsFromStartToEnd est 3
allPathsFromStartToEnd est 2

aussi possiblyHasEarlyReturn est true


Cette erreur particulière est signalée lorsque pathsFromStartToEnd et allPathsFromStartToEnd sont inégaux.

Voir RulesOfHooks.js ligne 404


Si vous extrayez le code à l'intérieur de la boucle for..in dans une fonction distincte, l'erreur de lint disparaît.

Dans ce cas, pathsFromStartToEnd et allPathsFromStartToEnd tous deux égaux à 2 :

  const someObject = { propA: true, propB: false };
  const someFunction = (propName) => {
    if (propName === true) {
      console.log("something");
    } else {
      console.log("whatever");
    }
  }
  for (const propName in someObject) {
    someFunction(propName)
  }
  const [myState, setMyState] = useState(null);

Je ne sais toujours pas pourquoi.

@gaearon , j'ai créé un adressage MR et corrige ce problème (# 16853).

La principale raison pour laquelle cela se produit est que la valeur de allPathsFromStartToEnd est mal calculée.
Dans cet exemple, le nombre de chemins du début à la fin doit être de 3, mais la fonction renvoie 2.

La raison pour laquelle cela se produit est à cause de la mise en cache défectueuse des chemins cycliques. Donc, dans un graphe normal, nous avons également besoin de l'historique du chemin, mais cela ne prend qu'une liste d'éléments cycliques et les éléments menant à ce chemin ne sont pas connus.
En conséquence, lorsqu'une condition est utilisée dans un for...in obj , en fonction de la direction, nous pouvons perdre certains chemins.

C'est toujours un problème avec 2.4.0, une repro un peu plus simple:

import * as React from "react";

function Component() {
  let isLastEven = false;
  for (let x of [1, 2, 3]) {
    if (x % 2 == 0) {
      isLastEven = true;
    } else {
      isLastEven = false;
    }
  }
  let y = React.useMemo(() => 1, []);
  return <div>{y}</div>;
}

# 16853 peut-il être rouvert?

Cette page vous a été utile?
0 / 5 - 0 notes