できない.dev

React で「Invalid hook call」が解決できない

Hook をコンポーネント関数のトップレベル以外で呼んだ、または react が二重に読み込まれていると Invalid hook call が出る。
呼び出し位置と react / react-dom のバージョン整合を確認する。

#react#hooks#rules-of-hooks#invalid-hook-call

要約

Invalid hook call. Hooks can only be called inside of the body of a function component は、Hook の呼び出し位置が不正react が二重に読み込まれている ときに出る。useState などはコンポーネント関数か use で始まるカスタム Hook の トップレベル でしか呼べない。
位置とバージョン整合の 2 点を順に潰す。

よくある原因

  1. トップレベル以外で呼んでいる: 条件分岐・ループ・try、イベントハンドラやネストした関数の中で useState などを呼んでいる
  2. 対象外の関数から呼んでいる: 通常のユーティリティ関数やクラスコンポーネントから Hook を呼んでいる
  3. バージョン不一致: reactreact-dom のメジャーが揃っていない
  4. react の重複: モノレポや npm linkreact が 2 つ入り、Hook のディスパッチャが分裂している

解決策

1. トップレベルで呼ぶ

// NG: 条件の内側で呼んでいる
function Comp({ on }: { on: boolean }) {
  if (on) {
    const [v, setV] = useState(0);
  }
  return null;
}
 
// OK: 先に Hook、分岐はその後
function Comp({ on }: { on: boolean }) {
  const [v, setV] = useState(0);
  return on ? <span>{v}</span> : null;
}

呼び出し順を毎回同じにするのが Rules of Hooks の原則。

2. 呼べる場所か確認する

Hook を使ってよいのは関数コンポーネント本体か、名前が use で始まるカスタム Hook の中だけ。
それ以外の関数からロジックを切り出すときは、カスタム Hook 化する。

3. バージョンを揃える

npm ls react react-dom

reactreact-dom を同一メジャーに合わせる。
片方だけ更新した状態が典型的な不一致。

4. react の重複を解消する

npm dedupe
npm ls react      # 1 つだけになっているか確認

それでも 2 つ残るなら、bundler 側で react を単一パスに alias する。
重複時の詳しい対処は Invalid hook call 警告の公式解説 に整理されている。

この記事は役立ちましたか?