The text starts here~
Overview
There are several reasons for the "Invalid hook call. Hooks can only be called inside the body of a function component" error:
- The versions of
react
andreact-dom
do not match. - There are multiple
react
package versions in a project. - Attempt to call a component as a function, for example,
App()
instead of<App />
. - Use hooks inside classes, or in functions that are not components or custom hooks.
version match
Open a terminal at the root of the project and update the versions of the react
and react-dom
packages, making sure the versions match and that no outdated versions are used.
# 👇️ 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
If the error persists, try deleting node_modules
and package-lock.json
(not package.json
) files, re-run npm install
and restart your IDE.
This error is usually caused by having multiple versions of react
in the same project.
# 👇️ delete node_modules and package-lock.json
rm -rf node_modules
rm -f package-lock.json
# 👇️ clean npm cache
npm cache clean --force
npm install
If the error persists, make sure to restart the IDE and development services. VSCode crashes frequently and needs to be restarted.
call component
Here is another example to show how the error occurs.
// App.js
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>
);
}
The problem is that we are calling the App
component as a function.
You should only use components with JSX syntax. For example: <App country="Austria" age="30" />
instead of App({country: 'Austria', age: 30})
.
Make sure you are not calling the hook inside a class component, or a function that is neither a component nor a custom hook.
If you have a class, turn it into a function that can use hooks.
Below is an example of how an error can be caused in a function that is neither a component nor a custom hook.
// App.js
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
The function starts with lowercase c
, so it is not considered a component by React. Because all component names must start with a capital letter. It is also not a custom hook because its name does not start with use
, for example useCounter
.
We can only use hooks inside function components or custom hooks, so one way to be able to use hooks is to rename --- counter
--- to useCounter
.
import {useState, useEffect} from 'react';
function useCounter() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('hello world');
}, []);
}
Now React considers useCounter
a custom hook and allows us to use hooks inside it.
As the documentation says:
- Only call Hooks from React function components or custom hooks
- Only use hooks at the top level
- Don't call Hooks in loops, conditionals or nested functions
- Make sure to always use Hook at the top level of your React function and before any return
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。