响应17.0.1:挂钩调用无效。只能在函数组件的主体内部调用挂钩 [英] React 17.0.1: Invalid hook call. Hooks can only be called inside of the body of a function component

查看:26
本文介绍了响应17.0.1:挂钩调用无效。只能在函数组件的主体内部调用挂钩的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是非常新的Reaction用户。我已经对这个错误进行了数小时的故障排除。我以前让这个组件作为一个类工作,但最近似乎每个人都在向功能组件迁移,所以我正在尝试转换它。我在没有使用STATE的情况下执行了中间转换,它工作得很好,但在将用户名和密码转换为状态值时遇到了问题。

当我使用以下代码时,我得到一个错误:

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.

我已多次阅读链接的疑难解答页面,并尝试修复所有三个可能的原因,但均未成功。

  1. 我正在devDependencies中使用react17.0.1和react-dom17.0.1。
  2. 我已安装eslint-plugin-react-hooks规则以确定我是否在功能组件中正确使用挂钩。
  3. 我已使用npm ls reactnpm ls react-dom确认我没有重复的Reaction版本。

LoginForm.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,就好像它是普通函数,而不是作为反应组件:

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);
          //    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

这篇关于响应17.0.1:挂钩调用无效。只能在函数组件的主体内部调用挂钩的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆