无效的钩子调用。Hooks 只能在函数组件内部调用
Invalid hook call. Hooks can only be called inside the body of a function component
出现“Invalid hook call. Hooks can only be called inside of a function component”的错误有多种原因:
react
和的版本不匹配react-dom
。react
在同一个项目中有多个版本的包。- 尝试将组件作为函数调用,例如
App()
而不是<App />
- 在类内部或不是组件或自定义挂钩的函数中使用挂钩。
react
和 的版本不匹配react-dom
在项目的根目录中打开终端并
更新您的和包的版本react
react-dom
以确保版本匹配并且您没有使用过时的版本。
# 👇️ with NPM npm install react@latest react-dom@latest # 👇️ ONLY If you use TypeScript npm install --save-dev @types/react@latest @types/react-dom@latest # ---------------------------------------------- # 👇️ with YARN yarn add react@latest react-dom@latest # 👇️ ONLY If you use TypeScript yarn add @types/react@latest @types/react-dom@latest --dev
如果错误仍然存在,请尝试删除您的node_modules
和
package-lock.json(不是
package.json
)文件,重新运行npm install
并重新启动您的 IDE。
删除您的 node_modules 并重新安装您的依赖项
react
该错误通常是由于同一项目中有多个版本引起的。
bash
如果您使用的是 macOS 或 Linux,请在或中发出以下命令zsh
。
# for macOS and Linux rm -rf node_modules rm -f package-lock.json rm -f yarn.lock # 👇️ clean npm cache npm cache clean --force # 👇️ install packages npm install
如果您使用的是 Windows,请在 CMD 中发出以下命令。
# for Windows rd /s /q "node_modules" del package-lock.json del -f yarn.lock # 👇️ clean npm cache npm cache clean --force # 👇️ install packages npm install
如果错误仍然存在,请确保重新启动 IDE和开发服务器。VSCode 经常出现故障并需要重启。
将组件作为函数调用
这是错误如何发生的另一个示例。
import {useState} from 'react'; // 👇️ Don't call components as functions 👇️ App(); export default function App() { /** * ⛔️ Warning: Invalid hook call. Hooks can only be * called inside of the body of a function component. * This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app */ const [count, setCount] = useState(0); return ( <div> <h1>Hello world</h1> </div> ); }
App
组件作为函数调用。您应该只使用具有 JSX 语法的组件,例如
<App country="Austria" age="30" />
, 而不是
App({country: 'Austria', age: 30})
.
如果您有类,
请将其转换为函数以便能够使用钩子。
仅在组件和自定义钩子中使用钩子
这是一个错误是如何在既不是组件也不是自定义挂钩的函数中引起的示例。
import {useState, useEffect} from 'react'; // 👇️ not a component nor custom hook // so it can't use hooks function counter() { const [count, setCount] = useState(0); useEffect(() => { console.log('hello world'); }, []); }
该counter
函数以小写字母开头c
,因此 React 不将其视为组件,因为所有
组件名称都必须以大写字母开头。
它也不是自定义挂钩,因为它的名称不以开头use
,例如
useCounter
。
我们只能在函数组件或自定义钩子内部使用钩子,因此能够使用钩子的一种方法是重命名counter
为useCounter
.
import {useState, useEffect} from 'react'; function useCounter() { const [count, setCount] = useState(0); useEffect(() => { console.log('hello world'); }, []); }
React 现在识别useCounter
为自定义钩子,因此它允许我们在其中使用钩子。
就像
文档中指出的那样:
- 仅从 React 函数组件或自定义钩子调用钩子。
- 只在顶层调用钩子。
- 不要在循环、条件或嵌套函数中调用钩子。
- 在任何早期返回之前,始终在 React 函数的顶层使用钩子。
结论
要解决错误“无效的挂钩调用。挂钩只能在函数组件的主体内调用”,请确保:
react
和的版本之间没有不匹配react-dom
。- 您没有
react
安装多个版本。 - 您不是在尝试将组件作为函数调用,例如
App()
而不是
<App />
. - 不要在类或不是组件或自定义挂钩的函数内部使用挂钩。