機能をリクエストしバグを報告しますか?
バグ(おそらく)
現在の動作は何ですか?
プラグインはこのエラーを示しています:
Reactフック「useState」は条件付きで呼び出されます。 React Hookは、すべてのコンポーネントレンダリングでまったく同じ順序で呼び出す必要があります。 早期に戻った後、誤ってReact Hookを呼び出しましたか? (react-hooks / rules-of-hooks)eslint
しかし、条件付きでフックを呼んでいるとは思いません。
コード:
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>
);
}
期待される動作は何ですか?
この状況では、プラグインはエラーを表示しません。
Reactのどのバージョン、およびどのブラウザ/ OSがこの問題の影響を受けますか?
この特定の例では、次のことに気づきました。
pathsFromStartToEnd
は3
allPathsFromStartToEnd
は2
また、 possiblyHasEarlyReturn
はtrue
この特定のエラーは、 pathsFromStartToEnd
とallPathsFromStartToEnd
が等しくない場合に報告されます。
RulesOfHooks.jsの404行を参照してください
for..in
ループ内のコードを別の関数に抽象化すると、lintエラーはなくなります。
この場合、 pathsFromStartToEnd
とallPathsFromStartToEnd
どちらも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);
理由はまだわかりません。
@gaearon 、この問題に対処して修正するMRを作成しました(#16853)。
これが発生する主な理由は、 allPathsFromStartToEnd
値が正しく計算されていないことです。
この例では、開始から終了までのパスの数は3である必要がありますが、関数は2を返します。
これが発生する理由は、循環パスのキャッシュに欠陥があるためです。 したがって、通常のグラフトラバースでは、パス履歴も必要ですが、循環要素のリストのみが必要であり、このパスにつながる要素は不明です。
その結果、条件がfor...in obj
で使用される場合、方向に基づいて、いくつかのパスが失われる可能性があります。
これは2.4.0の問題であり、少し単純な再現です。
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を再開できますか?
最も参考になるコメント
https://github.com/facebook/react/pull/16853を統合しました