Möchten Sie eine Funktion anfordern oder einen Fehler melden?
BUG (möglicherweise)
Wie ist das aktuelle Verhalten?
Das Plugin zeigt diesen Fehler an:
React Hook "useState" wird bedingt aufgerufen. React Hooks müssen in jedem Komponenten-Rendering in genau derselben Reihenfolge aufgerufen werden. Haben Sie nach einer frühen Rückkehr versehentlich einen React Hook angerufen? (React-Hooks / Rules-of-Hooks) Eslint
Aber ich glaube nicht, dass ich irgendwelche Haken bedingt anrufe.
Der 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>
);
}
Was ist das erwartete Verhalten?
Das Plugin würde den Fehler in dieser Situation nicht anzeigen.
Welche Versionen von React und welcher Browser / welches Betriebssystem sind von diesem Problem betroffen?
Ich habe das für dieses spezielle Beispiel bemerkt:
pathsFromStartToEnd
ist 3
allPathsFromStartToEnd
ist 2
auch possiblyHasEarlyReturn
ist true
Dieser bestimmte Fehler wird gemeldet, wenn pathsFromStartToEnd
und allPathsFromStartToEnd
ungleich sind.
Siehe RulesOfHooks.js Zeile 404
Wenn Sie den Code innerhalb der for..in
-Schleife in eine separate Funktion abstrahieren, verschwindet der Flusenfehler.
In diesem Fall sind pathsFromStartToEnd
und allPathsFromStartToEnd
beide gleich 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);
Ich bin mir immer noch nicht sicher warum.
@gaearon , ich habe eine MR-Adressierung erstellt und dieses Problem behoben (# 16853).
Der Hauptgrund dafür ist, dass der Wert von allPathsFromStartToEnd
falsch berechnet wird.
In diesem Beispiel sollte die Anzahl der Pfade von Anfang bis Ende 3 betragen, die Funktion gibt jedoch 2 zurück.
Der Grund dafür ist das fehlerhafte Zwischenspeichern von zyklischen Pfaden. Beim normalen Durchlaufen von Graphen benötigen wir also auch den Pfadverlauf, es wird jedoch nur eine Liste der zyklischen Elemente benötigt, und die Elemente, die zu diesem Pfad führen, sind nicht bekannt.
Wenn eine Bedingung in einem for...in obj
, verlieren wir möglicherweise einige Pfade, basierend auf der Richtung.
Dies ist immer noch ein Problem mit 2.4.0, ein bisschen einfacher Repro:
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>;
}
Kann # 16853 erneut geöffnet werden?
Zusammengeführtes https://github.com/facebook/react/pull/16853.
Hilfreichster Kommentar
Zusammengeführtes https://github.com/facebook/react/pull/16853.