React报错之Invalid hook call
正文从这开始~
总览
导致"Invalid hook call. Hooks can only be called inside the body of a function component"错误的有多种原因:
react
和react-dom
的版本不匹配。- 在一个项目中有多个
react
包版本。 - 试图将一个组件作为一个函数来调用,例如,
App()
而不是<App />
。 - 在类里面使用钩子,或者在不是组件或自定义钩子的函数中使用钩子。
版本匹配
在项目的根目录下打开终端,更新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。
这个错误通常是由于在同一个项目中拥有多个版本的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的更多相关文章
- Jade报错:Invalid indentation,you can use tabs or spaces but not both问题
现象:通过html生成jade文件之后,更改jade文件时,语句没什么问题的情况下,jade文件编译不通过,报错:Invalid indentation,you can use tabs or spa ...
- react 报错的堆栈处理
react报错 Warning: You cannot PUSH the same path using hash history 在Link上使用replace 原文地址https://reactt ...
- mysql创建表时,设置timestamp DEFAULT NULL报错1067 - Invalid default value for 'updated_at'
问题背景: 线上的linux服务器上的mysql服务器中导出数据库的结构.想要在本地创建一个测试版本 导出后再本地mysql上运行却报错 1067 - Invalid default value ...
- 数据库查询语句报错-ORA-00911: invalid character
数据库查询语句报错-ORA-00911: invalid character 根据自己经验总结下: 1.都是分号惹的祸,有时候sql语句后面有分好导致这种错误 2.还有一种是从别处copy过来的sql ...
- CocoaPods pod install的时候报错:invalid byte sequence in UTF-8 (ArgumentError)解决办法
CocoaPods pod install的时候报错:invalid byte sequence in UTF-8 (ArgumentError)解决办法: 基本可以确定是Podfile中的内容编码有 ...
- ssh调用matplotlib绘图报错RuntimeError: Invalid DISPLAY variable
1.问题:在本地用matplotlib绘图可以,但是在ssh远程绘图的时候会报错 RuntimeError: Invalid DISPLAY variable 2.原因:matplotlib的默认ba ...
- golang解析json报错:invalid character '\x00' after top-level value
golang解析json报错:invalid character '\x00' after top-level value 手动复制字符串:{"files":["c:/t ...
- mybatis报错:Invalid bound statement (not found)
mybatis报错:Invalid bound statement (not found)的原因很多,但是正如报错提示一样,找不到xml中的sql语句,报错的情况分为三种: 第一种:语法错误 Java ...
- 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 ...
随机推荐
- plt.figure()的使用,plt.plot(),plt.subplot(),plt.subplots()和图中图
参考:https://blog.csdn.net/m0_37362454/article/details/81511427 matplotlib官方文档:https://matplotlib.org/ ...
- 使用kubeseal加密和管理k8s集群的secret
使用kubeseal加密和管理k8s集群的secret 在k8s的管理过程中,像secret这种资源并不好维护,kubeseal提供了一种相对简单的方式来对原始secret资源进行加密,并通过控制器进 ...
- redis主从复制(九)
先来简单了解下redis中提供的集群策略, 虽然redis有持久化功能能够保障redis服务器宕机也能恢复并且只有少量的数据损失,但是由于所有数据在一台服务器上,如果这台服务器出现硬盘故障,那就算是有 ...
- tomcat 的安全配置预防后台被攻击
安全是系统架构中最重要的关注点之一,通常情况下,所说的安全涵盖网络安全.数据安全.操作系统安全.服务器安全以及应用系统安全等诸多方面. Tomcat 是一个免费的开放源代码 的Web应用服务器,技术先 ...
- 毕设必看——Python ttkbootstrap 制作账户注册信息界面
先来哔哔两句:(https://jq.qq.com/?_wv=1027&k=QgGWqAVF) ttkbootstrap 是一个基于 tkinter 的界面美化库,使用这个工具可以开发出类似前 ...
- Java中将对象或者集合对象转换成json字符串
1.对象和字符串相互转换 2.集合对象和字符串相互转换
- Node.js精进(10)——性能监控(下)
本节会重点分析内存和进程奔溃,并且会给出相应的监控方法. 本系列所有的示例源码都已上传至Github,点击此处获取. 一.内存 虽然在 Node.js 中并不需要手动的对内存进行分配和销毁,但是在开发 ...
- 一文吃透如何部署kubernetes之Dashboard
kubernetes Dashboard是什么? Dashboard是kubernetes的Web GUI,可用于在kubernetes集群上部署容器化应用,应用排错,管理集群本身及其附加的资源等,它 ...
- 【Unity基础知识】基础游戏单位GameObject中常用的属性和API
一.GameObject中的成员变量 主要思想:得到该脚本依附的GameObject的相关信息 现有: Lesson4的代码: using System.Collections; using Syst ...
- dfs-1756:八皇后及1700:八皇后问题
总时间限制: 1000ms 内存限制: 65536kB 描述 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被 ...