正文从这开始~

总览

导致"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. Anaconda新建虚拟环境并添加到Jupyter Notebook

    可参考:https://www.jianshu.com/p/ab9ae548b253 虚拟环境是Python的隔离工作副本.这意味着每个环境都可以具有自己的依赖关系,甚至可以具有自己的Python版本 ...

  2. 【Redis】简单动态字符串SDS

    C语言字符串 char *str = "redis"; // 可以不显式的添加\0,由编译器添加 char *str = "redis\0"; // 也可以添加 ...

  3. 分享一个网上搜不到的「Redis」实现「聊天回合制」的方案

    前言 为什么说网上搜不到,因为关于聊天回合制的方案作者本人快把百度搜秃噜了也没找到,好在最终是公司一个关系不错的大佬帮提供了点思路,最终作者将其完整实现了出来. 分享出来大家可以收藏,万一你哪天也碰到 ...

  4. ABP框架之——数据访问基础架构(下)

    大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的一块垫脚石,我们一起精进. EF Core集成 EF Core是微软的ORM,可以使用它与主流的数据库提供商 ...

  5. Python:一个闹钟

    随着一个<霍格沃茨:一段校史>风格的大字(呃,这字好像并不大--)标题的出现,无聊的我没事干,又开始整活了~ 之前我做的程序,一个使用了Tkinter库,一个则是Pygame,总之都是带有 ...

  6. idea 查看 类所有方法的快捷键

    idea 查看 类 所有方法的快捷键 Idea:ctrl+F12 Eclipse:Ctrl+O

  7. Linux查看内网服务器的出口IP

    查看内网服务器的出口IPcurl ifconfig.me [root@vpnserver ~]# curl ifconfig.me111.10.100.100 [root@vpnserver ~]#

  8. Proxmox-VE虚拟环境

  9. Graph-Based Social Relation Reasoning

    title: Graph-Based Social Relation Reasoning, 2020 task: we propose a simpler, faster, and more accu ...

  10. pytorch 基础内容

    一些基础的操作: import torch as th a=th.rand(3,4) #随机数,维度为3,4的tensor b=th.rand(4)print(a)print(b) a+b tenso ...