Hooks(useState、useEffect など)には 2 つのルールがあります。
- hook は top level でだけ呼び出す — 条件分岐、loop、ネストした関数の中では呼び出さない。
- hook は React function からだけ呼び出す — component または custom hook から呼び出す。
jsx
() {
[user, setUser] = ();
(id) {
[x] = ();
}
}
Hooks(useState、useEffect など)には 2 つのルールがあります。
() {
[user, setUser] = ();
(id) {
[x] = ();
}
}
ジュニアからシニアまで、詳細な回答付きのIT面接質問ライブラリ。
寄付するReact は hook を名前で識別しているわけではありません。呼び出し順に依存しています。各 render で、React はまったく同じ順序で hook をたどり、それぞれの呼び出しを内部 list の slot に対応付けます。
Render 1: useState(A) → slot 0, useState(B) → slot 1, useEffect → slot 2
Render 2: useState(A) → slot 0, useState(B) → slot 1, useEffect → slot 2
hook を条件付きで呼ぶと、render 間で順序が変わる可能性があります。すると slot 1 がある render では useState(B)、次の render では useEffect になるかもしれません。React は間違った state を間違った hook に渡してしまい、全体が壊れます。
hook 自体は無条件に呼び出し、条件はその中に置くか、返された値に基づいて分岐します。
const [user, setUser] = useState(null);
useEffect(() => {
if (!id) return; // 条件は effect の内側。effect を囲まない
fetchUser(id).then(setUser);
}, [id]);
eslint-plugin-react-hooks の lint rule は、これらのルールを自動で強制してくれます。