惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
The Last Watchdog
The Last Watchdog
T
Tenable Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
Simon Willison's Weblog
Simon Willison's Weblog
V
Vulnerabilities – Threatpost
F
Fortinet All Blogs
Microsoft Security Blog
Microsoft Security Blog
A
Arctic Wolf
云风的 BLOG
云风的 BLOG
Know Your Adversary
Know Your Adversary
P
Palo Alto Networks Blog
GbyAI
GbyAI
阮一峰的网络日志
阮一峰的网络日志
The GitHub Blog
The GitHub Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
U
Unit 42
MyScale Blog
MyScale Blog
B
Blog
Spread Privacy
Spread Privacy
S
Schneier on Security
Project Zero
Project Zero
L
LINUX DO - 热门话题
M
MIT News - Artificial intelligence
F
Full Disclosure
WordPress大学
WordPress大学
Apple Machine Learning Research
Apple Machine Learning Research
Cyberwarzone
Cyberwarzone
AWS News Blog
AWS News Blog
aimingoo的专栏
aimingoo的专栏
博客园 - 三生石上(FineUI控件)
C
Cybersecurity and Infrastructure Security Agency CISA
Hugging Face - Blog
Hugging Face - Blog
Security Latest
Security Latest
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Tailwind CSS Blog
K
Kaspersky official blog
Recent Announcements
Recent Announcements
NISL@THU
NISL@THU
Cisco Talos Blog
Cisco Talos Blog
S
Securelist
P
Privacy & Cybersecurity Law Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
The Exploit Database - CXSecurity.com
V
Visual Studio Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Webroot Blog
Webroot Blog

Deed's博客

解决群晖百度套件提示name "baiduapp" dupliacted - Deed's博客 2023年3月16日 Maven项目引入第三方本地jar包 - Deed's博客 2022年8月23日nginx反向代理配置去除前缀 - Deed's博客 2022年8月1日 ts-node 运行报错`Cannot find name 'console'.` 2022年7月13日 Gradle项目打包相关配置 - Deed's博客 2022年6月23日 Windows 杀死进程 - Deed's博客 2022年6月16日 查看服务器异常IP访问以及处理 - Deed's博客 2022年6月15日 Linux删除用户 - Deed's博客 2022年6月8日 AntDesignPro文档Demo示例[后置拦截器]报错 - Deed's博客
2022年6月8日 React使用umi.js报错Invalid hook call - Deed's博客
Mahalalel · 2022-06-08 · via Deed's博客
«

Mahalalel 发布于 阅读:5606 React


报错详情

在写React项目的Demo的时候,使用umi中useHistory,调用运行时,报了以下错误

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

翻译如下:

无效的挂钩调用。 钩子只能在函数组件的主体内部调用。 这可能由于以下原因之一而发生:
1. React 和渲染器的版本可能不匹配(例如 React DOM)
2. 你可能违反了 Hooks 规则
3. 你可能在同一个应用程序中拥有多个 React 副本

代码

import { doLogin } from '@/api/user/user';
import { Button, Form, Input, message } from 'antd';
import { useHistory } from 'umi';

const history = useHistory();
const login = (user: API.IUser) => {
  doLogin(user).then(res => {
    console.log(res);

    if (res.code === 200) {
      message.success({
        content: "用户" + user.username + "登录成功",
        onClose: () => {
          history.push("/")
        }
      });
    } else {
      message.error("登录失败");
    }
  })
}

function Index() {
  return (
    <>
      <Form
        onFinish={login}
        labelCol={{ span: 6 }}
        wrapperCol={{ span: 12 }}
      >
        <Form.Item
          label={'用户名'} name={'username'}
          rules={[
            {
              required: true,
              type: 'string',
              message: '用户名不允许为空'
            }
          ]}
        >
          <Input />
        </Form.Item>
        <Form.Item
          label={'密码'} name={'password'}
          rules={[
            {
              required: true,
              type: 'string',
              message: '密码不允许为空'
            },
            {
              max: 20,
              min: 10,
              message: '密码长度在10~20之间'
            },
            {

            }
          ]}
        >
          <Input.Password />
        </Form.Item>
        <Form.Item wrapperCol={{ offset: 6, span: 12 }}>
          <Button type="primary" htmlType="submit">
            登录
          </Button>
          <Button type="default" style={{ marginLeft: 10 }} htmlType="reset">
            重置
          </Button>
        </Form.Item>
      </Form>
    </>
  );
}

export default Index;

解决

排查后发现,原来是
const history = useHistory();
这句初始化代码写在了组件外面,导致异常。

底层逻辑如下图
react-hooks

截图来自链接:react-hooks原理

将代码移入组件内部,错误解决了,代码如下


import { doLogin } from '@/api/user/user';
import { Button, Form, Input, message } from 'antd';
import { useHistory } from 'umi';

function Index() {
  const history = useHistory();
  const login = (user: API.IUser) => {
    doLogin(user).then(res => {
      console.log(res);

      if (res.code === 200) {
        message.success({
          content: "用户" + user.username + "登录成功",
          onClose: () => {
            history.push("/")
          }
        });
      } else {
        message.error("登录失败");
      }
    })
  }
  ...
}

export default Index;

React Hooks报错