reactjs - React 17.0.1:无效的钩子调用。Hooks 只能在函数组件的主体内部调用
问题描述
非常新的反应用户在这里。我已经解决这个错误几个小时了。我以前有这个组件作为一个类工作,但最近似乎每个人都在向功能组件迁移,所以我正在尝试转换它。我在不使用状态的情况下进行了中间转换,并且效果很好,但是在将用户名和密码转换为状态值时遇到了麻烦。
当我使用以下代码时,出现错误:
Uncaught Error: 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
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
我已多次阅读链接的故障排除页面,并尝试修复所有三个可能的原因,但均未成功。
- 我在我
react
的.react-dom
devDependencies
- 我已经安装了
eslint-plugin-react-hooks
规则来识别我是否在我的功能组件中没有正确使用钩子。 - 我已经使用
npm ls react
并npm ls react-dom
确认我没有重复的反应版本。
登录表单.jsx
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
const $ = require('jquery');
const LoginForm = ({ onToken }) => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const submit = (event) => {
// DO NOT POST PARAMS
event.preventDefault();
// AJAX username and password
const loginData = {
username: username,
password: password
};
const options = {
url: 'api/login',
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify(loginData),
success: (data) => {
console.log(data);
onToken(data.token);
}
};
$.ajax(options);
console.log('Submitted!');
};
return (
<form onSubmit={submit}>
<label htmlFor="username">Username:</label><br/>
<input value={username} onChange={e => setUsername(e.target.value)} type="text" id="username" name="username"/><br/>
<label htmlFor="password">Password:</label><br/>
<input value={password} onChange={e => setPassword(e.target.value)} type="password" id="password" name="password"/><br/>
<input type="submit" value="Login"/>
</form>
);
};
LoginForm.propTypes = {
onToken: PropTypes.func
};
export default LoginForm;
我在项目的存储库上创建了一个分支,以便您查看任何其他信息:
分支:https ://github.com/GibsDev/node-password-manager/tree/login-conversion
提交:https ://github.com/GibsDev/node-password-manager/commit/e0714b16bdbbf339fabf1aa4f6eefacd6d053427
解决方案
您将其loginForm
称为普通函数,而不是 React 组件:
const loginForm = LoginForm({
onToken: token => {
const url = new URL(window.location.href);
const returnurl = url.searchParams.get('returnurl');
if (returnurl) {
window.location.href = decodeURIComponent(returnurl);
} else {
window.location.href = '/';
}
}
});
ReactDOM.render(loginForm, domContainer);
结果,它没有被包裹在 中React.createElement
,所以它认为钩子调用是无效的。
改用 JSX 语法:
const onToken = token => {
const url = new URL(window.location.href);
const returnurl = url.searchParams.get('returnurl');
if (returnurl) {
window.location.href = decodeURIComponent(returnurl);
} else {
window.location.href = '/';
}
}
ReactDOM.render(<LoginForm onToken={onToken} />, domContainer);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
推荐阅读
- asp.net - 使用 SQLite 数据库在 Azure 上发布时出现“实体框架 SQL 脚本生成失败”错误
- i2c - 为什么 `i2c_smbus_write_byte_data` 在 uClinux 2.4 上会返回“不允许操作”?
- html - 在私有 Bitbucket 服务器上呈现单个 HTML 页面
- javascript - viewer.getPlugin(PhotoSphereViewer.MarkersPlugin) 返回 null
- python - cx_Freeze:Python 错误主脚本。找不到模块错误:没有名为 pygments.lexers.python 的模块
- c# - ML.NET 是否支持带有 RBF 内核的 SVM?
- android - 颤振用户身份验证
- qt - Qt Widget 点击 2D pos 到 3D 世界坐标
- php - 将 PDO 准备好的语句放在 DB_Connector 类中的什么位置 - 在构造函数或函数中?
- git - 如何读取子模块的 .git/index 文件