正文从这开始~

总览

导致"Invalid hook call. Hooks can only be called inside the body of a function component"错误的有多种原因:

  1. reactreact-dom的版本不匹配。
  2. 在一个项目中有多个react包版本。
  3. 试图将一个组件作为一个函数来调用,例如,App()而不是<App />
  4. 在类里面使用钩子,或者在不是组件或自定义钩子的函数中使用钩子。

版本匹配

在项目的根目录下打开终端,更新reactreact-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。

这个错误通常是由于在同一个项目中拥有多个版本的react造成的。

# ️ 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

如果错误仍然存在,请确保重启了IDE和开发服务。VSCode经常出现故障,需要重启。

调用组件

这里有另一个示例,用来展示错误是如何发生的。

// 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>
);
}

问题在于,我们将App组件作为函数进行调用。

你应该只使用具有JSX语法的组件。比如:<App country="Austria" age="30" />,而不是App({country: 'Austria', age: 30})

确保你没有在一个类组件,或一个既不是组件也不是自定义钩子的函数里面调用钩子。

如果你有一个类,请将其转换为能够使用钩子的函数。

下面是一个例子,说明在一个既不是组件也不是自定义钩子的函数中是如何引起错误的。

// 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函数以小写的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函数组件或自定义钩子中调用Hook
  • 只在最顶层使用 Hook
  • 不要在循环,条件或嵌套函数中调用 Hook
  • 确保总是在你的 React 函数的最顶层以及任何 return 之前使用 Hook

React报错之Invalid hook call的更多相关文章

  1. Jade报错:Invalid indentation,you can use tabs or spaces but not both问题

    现象:通过html生成jade文件之后,更改jade文件时,语句没什么问题的情况下,jade文件编译不通过,报错:Invalid indentation,you can use tabs or spa ...

  2. react 报错的堆栈处理

    react报错 Warning: You cannot PUSH the same path using hash history 在Link上使用replace 原文地址https://reactt ...

  3. mysql创建表时,设置timestamp DEFAULT NULL报错1067 - Invalid default value for 'updated_at'

    问题背景: 线上的linux服务器上的mysql服务器中导出数据库的结构.想要在本地创建一个测试版本 导出后再本地mysql上运行却报错   1067 - Invalid default value ...

  4. 数据库查询语句报错-ORA-00911: invalid character

    数据库查询语句报错-ORA-00911: invalid character 根据自己经验总结下: 1.都是分号惹的祸,有时候sql语句后面有分好导致这种错误 2.还有一种是从别处copy过来的sql ...

  5. CocoaPods pod install的时候报错:invalid byte sequence in UTF-8 (ArgumentError)解决办法

    CocoaPods pod install的时候报错:invalid byte sequence in UTF-8 (ArgumentError)解决办法: 基本可以确定是Podfile中的内容编码有 ...

  6. ssh调用matplotlib绘图报错RuntimeError: Invalid DISPLAY variable

    1.问题:在本地用matplotlib绘图可以,但是在ssh远程绘图的时候会报错 RuntimeError: Invalid DISPLAY variable 2.原因:matplotlib的默认ba ...

  7. golang解析json报错:invalid character '\x00' after top-level value

    golang解析json报错:invalid character '\x00' after top-level value 手动复制字符串:{"files":["c:/t ...

  8. mybatis报错:Invalid bound statement (not found)

    mybatis报错:Invalid bound statement (not found)的原因很多,但是正如报错提示一样,找不到xml中的sql语句,报错的情况分为三种: 第一种:语法错误 Java ...

  9. git commit -m "XX"报错 pre -commit hook failed (add --no-verify to bypass)问题

    在同步本地文件到线上仓库的时候 报错 pre -commit hook failed (add --no-verify to bypass) 当你在终端输入git commit -m "xx ...

随机推荐

  1. 更换conda镜像源、pip镜像源

    镜像源一般有两点特别需要注意,一个是Conda源,一个是Pip源: 更换Conda源,以更换清华Conda源为例: Anaconda 镜像使用帮助 Anaconda 是一个用于科学计算的 Python ...

  2. bare Git 仓库是什么?

    背景 今天,坐我旁边的同事问我一些关于服务器上命令的问题.其中有一个用了特殊参数的 git init 的命令,我也不认识,遂去 Google... bare Git 仓库 定义 A bare Git ...

  3. 认识一下什么是JSP

    摘要:JSP,全称是Java Server Pages,即Java服务器页面,是由Sun Microsystems公司主导创建的一种动态网页技术标准. 本文分享自华为云社区<Java服务器页面- ...

  4. Vmware 10~16激活码/序列号 汇总

    Vmware 16 ZF3R0-FHED2-M80TY-8QYGC-NPKYF YF390-0HF8P-M81RQ-2DXQE-M2UT6 ZF71R-DMX85-08DQY-8YMNC-PPHV8 ...

  5. 领导:谁再用redis过期监听实现关闭订单,立马滚蛋!

    日前拜读阿牛老师的大作 领导:谁再用定时任务实现关闭订单,立马滚蛋! 发现其方案有若干瑕疵,特此抛砖引玉讨论一二. 在电商.支付等领域,往往会有这样的场景,用户下单后放弃支付了,那这笔订单会在指定的时 ...

  6. 开启网易邮箱客户端授权码-POP/SMTP/IMAP

    打开网易邮箱首页 https://mail.163.com/ 登录邮箱. 点击上方设置,选择POP/SMTP/IMAP选项. 选择开启对应的协议,IMAP或者POP3分别为不同的收信协议 在新弹出的弹 ...

  7. zip格式文件编码检测

    解压后文件名乱码 由于zip格式文件无编码存储的结构,因此解压时无法知道原先的编码. 当解压zip格式文件时使用的编码和原编码不一致时,就可能会出现解压后文件名乱码问题. 猜测编码 基于上述问题,需要 ...

  8. ModuleNotFoundError: No module named 'distutils.spawn'

    解决办法: 安装python3-distutils sudo apt-get install python3-distutils

  9. 揭开服务网格~Istio Service Mesh神秘的面纱

    目录 一.写在前面 二.微服务与K8S 三.服务网格与K8S 四.常见的产品 五.Istio架构 六.Istio的核心资源介绍 6.1.VirtualService 6.2.Destination R ...

  10. 出现 Expected 0 arguments but found 1 的bug原因

    问题:在给FileInputStream传入参数时报错 原以为是导错了包,结果试了几次都不行,最后才发现是项目名和这个方法名重复了,修改项目名就可以了! 红线出只是异常,抛出即可解决