Você quer solicitar um recurso ou relatar um bug ?
BUG (possivelmente)
Qual é o comportamento atual?
O plugin está mostrando este erro:
O React Hook "useState" é chamado condicionalmente. Os Ganchos React devem ser chamados exatamente na mesma ordem em cada renderização de componente. Você acidentalmente chamou um React Hook após um retorno antecipado? (react-hooks / rules-of-hooks) eslint
Mas não acho que estou chamando nenhum gancho condicionalmente.
O 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>
);
}
Qual é o comportamento esperado?
O plugin não mostraria o erro nesta situação.
Quais versões do React e quais navegadores / sistemas operacionais são afetados por esse problema?
Percebi que para este exemplo específico:
pathsFromStartToEnd
é 3
allPathsFromStartToEnd
é 2
também possiblyHasEarlyReturn
é true
Este erro específico é relatado quando pathsFromStartToEnd
e allPathsFromStartToEnd
são desiguais.
Consulte a linha 404 de RulesOfHooks.js
Se você abstrair o código dentro do loop for..in
em uma função separada, o erro de lint desaparece.
Neste caso, pathsFromStartToEnd
e allPathsFromStartToEnd
ambos iguais 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);
Ainda não tenho certeza do porquê.
@gaearon , criei um MR abordando e corrigindo esse problema (# 16853).
A principal razão para isso acontecer é que o valor de allPathsFromStartToEnd
foi calculado incorretamente.
Neste exemplo, o número de caminhos do início ao fim deve ser 3, mas a função retorna 2.
A razão pela qual isso acontece é devido ao armazenamento em cache defeituoso de caminhos cíclicos. Portanto, na travessia normal de um gráfico, precisamos também do histórico do caminho, mas leva apenas uma lista de elementos cíclicos e os elementos que levam a esse caminho não são conhecidos.
Como resultado, quando uma condição é usada em for...in obj
, com base na direção, podemos perder alguns caminhos.
Este ainda é um problema com o 2.4.0, uma reprodução um pouco mais simples:
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>;
}
pode # 16853 ser reaberto?
Comentários muito úteis
Https://github.com/facebook/react/pull/16853 mesclado