正文从这开始~

总览

导致"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. [学习笔记]使用Docker+Jenkin自动化流水线发布.Net应用

    ​使用Docker容器方案可以快速安全地将项目部署到客户的服务器上,作为公司项目,需要解决两个问题: 1. 需要搭建一个私有的Docker仓库,以便安全的存储镜像 2. 需要一套自动化发布方案,实现代 ...

  2. Canal-监听数据库表的变化

    1. 简介 Canal是阿里巴巴旗下的一款开源项目,纯Java开发.基于数据库增量日志解析,提供增量数据订阅&消费功能. 工作原理 Mysql主备复制原理 MySQL master 将数据变更 ...

  3. Spire.Office激活

    更新记录: 2022年5月28日 初始代码便于复用 注意:最多支持到:E-ICEBLUE Spire.Office Platinum v6.10.3 引入命名空间: using Spire.Licen ...

  4. WPF开发随笔收录-报警闪烁效果实现

    一.前言 工作中目前经手的项目是医疗相关的监护软件,所以会涉及到一些报警效果的实现,今天在这里就简单分享一下实现方式 二.正文 1.实现的方式比较的简单,就是通过一个Border控件,然后搭配Data ...

  5. 《HelloGitHub》第 75 期

    兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣.入门级的开源项目. https://github.com/521xueweiha ...

  6. Qt数据可视化(散点图、折线图、柱状图、盒须图、饼状图、雷达图)开发实例

    ​  目录 散点图 折线图 柱状图 水平柱状图 水平堆叠图 水平百分比柱状图 盒须图 饼状图 雷达图 Qt散点图.折线图.柱状图.盒须图.饼状图.雷达图开发实例. 在开发过程中我们会使用多各种各样的图 ...

  7. svn提交报错Unexpected HTTP status 413 'Request Entity Too Large' on

    问题原因:nginx的client_max_body_size设置过小,默认 1M,如果请求的正文数据大于client_max_body_size,HTTP协议会报错 413 Request Enti ...

  8. Rabbimtq消息传递对象

    对象序列化即可.

  9. 查询效率提升10倍!3种优化方案,帮你解决MySQL深分页问题

    开发经常遇到分页查询的需求,但是当翻页过多的时候,就会产生深分页,导致查询效率急剧下降. 有没有什么办法,能解决深分页的问题呢? 本文总结了三种优化方案,查询效率直接提升10倍,一起学习一下. 1. ...

  10. TypeScript 接口继承

    1.TypeScript 接口继承 和类一样,接口也可以通过关键字 extents 相互继承.接口继承,分为:单继承和多继承,即继承多个接口.另外,接口也可以继承类,它会继承类的成员,但不包括具体的实 ...