React: eslint-plugin-react-hooks: 'El gancho se está llamando condicionalmente' error fuera de la condición

Creado en 19 sept. 2019  ·  4Comentarios  ·  Fuente: facebook/react

¿Quieres solicitar una función o informar de un error ?

ERROR (posiblemente)

¿Cuál es el comportamiento actual?

El complemento muestra este error:

React Hook "useState" se llama condicionalmente. Los React Hooks deben llamarse en el mismo orden exacto en cada renderizado de componentes. ¿Llamaste accidentalmente a un React Hook después de un regreso anticipado? (react-hooks / reglas-de-hooks) eslint

Pero no creo que esté llamando a ningún gancho condicionalmente.

El código:

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

¿Cuál es el comportamiento esperado?

El complemento no mostraría el error en esta situación.

¿Qué versiones de React y qué navegador / sistema operativo se ven afectados por este problema?

image

ESLint Rules Bug

Comentario más útil

Todos 4 comentarios

Me di cuenta de que para este ejemplo en particular:

pathsFromStartToEnd es 3
allPathsFromStartToEnd es 2

también possiblyHasEarlyReturn es true


Este error en particular se informa cuando pathsFromStartToEnd y allPathsFromStartToEnd son iguales.

Ver RulesOfHooks.js línea 404


Si abstrae el código dentro del ciclo for..in en una función separada, el error de pelusa desaparece.

En este caso, pathsFromStartToEnd y allPathsFromStartToEnd ambos iguales a 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);

Todavía no estoy seguro de por qué.

@gaearon , creé un MR para abordar y solucionar este problema (# 16853).

La principal razón por la que esto sucede es que el valor de allPathsFromStartToEnd se calcula incorrectamente.
En este ejemplo, el número de rutas de principio a fin debería ser 3, pero la función devuelve 2.

La razón por la que esto sucede es debido al almacenamiento en caché defectuoso de las rutas cíclicas. Entonces, en el recorrido normal de un gráfico, también necesitamos el historial de la ruta, pero solo se necesita una lista de elementos cíclicos, y los elementos que conducen a esta ruta no se conocen.
Como resultado, cuando se usa una condición en un for...in obj , según la dirección, podemos perder algunas rutas.

Esto sigue siendo un problema con 2.4.0, una reproducción un poco más 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>;
}

¿Se puede reabrir el # 16853?

¿Fue útil esta página
0 / 5 - 0 calificaciones