错误: 无效的钩子调用。钩子只能在函数组件的主体内部调用。可能的原因:1. React 和渲染器(如 React DOM)版本不匹配;2. 违反了钩子规则;3. 同一个应用中有多个 React 副本。
Error: Invalid hook call. Hooks can only be called inside 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
ID: react/error-invalid-call-of-useeffect-in-callback
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| React 18.2.0 | active | — | — | — |
| React 17.0.2 | active | — | — | — |
| React 16.14.0 | active | — | — | — |
根因分析
钩子(例如 useEffect、useState)在普通 JavaScript 函数、回调或类组件中被调用,违反了钩子规则,要求钩子必须在 React 函数组件的顶层调用。
English
A hook (e.g., useEffect, useState) is being called inside a regular JavaScript function, callback, or class component, violating the Rules of Hooks that require hooks to be called at the top level of a React function component.
官方文档
https://react.dev/warnings/invalid-hook-call-warning解决方案
-
Ensure all hook calls are at the top level of a function component, never inside loops, conditions, or nested functions. Example: function MyComponent() { useEffect(() => { /* ... */ }, []); return <div />; } -
Check for duplicate React instances in your bundle by running `npm ls react` and ensure only one version exists. If using webpack, add `resolve: { alias: { react: require.resolve('react') } }` to webpack config. -
Convert class components to function components if you need to use hooks. Example: class MyComp extends Component { render() { return <div />; } } becomes function MyComp() { return <div />; }
无效尝试
常见但无效的做法:
-
Move the hook call to the top of a class component's render method
100% 失败
Hooks are not supported in class components; they must be used in function components.
-
Wrap the hook call in a try-catch block
95% 失败
The error is thrown as an invariant, not a catchable exception, and try-catch doesn't prevent the violation.
-
Use React.forwardRef to pass hooks to child components
90% 失败
forwardRef doesn't change where hooks can be called; hooks still must be in the component body.