gpt4 book ai didi

javascript - React - 错误 : Invalid hook call. Hooks 只能在函数组件的主体内部调用。我的语法有什么问题?

转载 作者:行者123 更新时间:2023-12-05 00:34:49 25 4
gpt4 key购买 nike

提供一点背景:
我正在尝试构建一个登录表单页面功能来检测用户是否已经登录。如果他们已登录,则会出现一个按钮,提示用户注销。像这样: {user ? userLoggedInAlert() : SignIn()}如果 user为 True,则出现按钮,如果 user为假,然后他们会收到用于登录身份验证的用户名和密码表单。
我已经确定了所有功能。
但是,当我按下 的按钮时注销 用户退出,我收到此错误:

×
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.
这是我的代码,我认为 const userLoggedInAlert 有问题
import React from 'react';
import { useSelector } from 'react-redux';
import { selectUser } from '../../features/userSlice';
import SignIn from '../auth/Login';
import Container from '@material-ui/core/Container';
import { Button } from '@material-ui/core';
import { logout } from "../../features/userSlice";
import { NavLink } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import LogOut from '../auth/Logout';



function LoginUser()
{
const user = useSelector(selectUser);

const dispatch = useDispatch();

const handleLogout = (e) =>
{
if(e) e.preventDefault();

dispatch(logout());
};

const userLoggedInAlert = () =>
{
return <Container>
<span>
You are already logged in!
</span>
<Button
component={NavLink}
variant="contained"
color="primary"
to="/logout"
onClick={function(){ LogOut(); handleLogout()}}
>
Do you want to logout?
</Button>

</Container>
};

return (
<Container>
{user ? userLoggedInAlert() : SignIn()}
</Container>
);
}
export default LoginUser;
  • SignIn()工作得很好,我的useDispatch也是如此,以及创建上述代码所需的其他组件。我很确定我只是弄乱了上面代码中某处的语法?

  • 这是我的代码 LogOut() ,请注意,我可以使用完全相同的组件通过其他方式注销。
    import React, { useEffect } from 'react';
    import axiosInstance from '../../axios';
    import { useHistory } from 'react-router-dom';

    export default function LogOut() {

    const history = useHistory();


    useEffect(() => {
    const response = axiosInstance.post('user/logout/blacklist/', {
    refresh_token: localStorage.getItem('refresh_token'),
    });
    localStorage.removeItem('access_token');
    localStorage.removeItem('refresh_token');
    axiosInstance.defaults.headers['Authorization'] = null;
    history.push('/login');
    });
    return <div>Logout</div>;
    };
    感谢您的帮助,我被困在这里。
    编辑:
      "dependencies": {
    "@material-ui/core": "^4.11.2",
    "@material-ui/icons": "^4.11.2",
    "@material-ui/lab": "^4.0.0-alpha.57",
    "@reduxjs/toolkit": "^1.5.0",
    "@testing-library/jest-dom": "^5.11.6",
    "@testing-library/react": "^11.2.2",
    "@testing-library/user-event": "^12.6.0",
    "axios": "^0.21.1",
    "chart.js": "^2.9.4",
    "react": "^17.0.1",
    "react-chartjs-2": "^2.11.1",
    "react-dom": "^17.0.1",
    "react-facebook-login": "^4.1.1",
    "react-hook-form": "^6.14.2",
    "react-redux": "^7.2.2",
    "react-router-dom": "^5.2.0",
    "react-scripts": "4.0.1",
    "redux": "^4.0.5",
    "redux-persist": "^6.0.0",
    "web-vitals": "^0.2.4"
    },
    编辑编辑:
    我正在努力实现建议的更改,现在我遇到了一些让我感到困惑的错误:
    Uncaught Error: Objects are not valid as a React child (found: object with keys {logoutUser}). If you meant to render a collection of children, use an array instead.
    上述错误发生在 <useLogOut>零件。
    这是我的实现方式: LoginPortal.js
    import React from 'react';
    import { useSelector } from 'react-redux';
    import { selectUser } from '../../features/userSlice';
    import SignIn from '../auth/Login';
    import Container from '@material-ui/core/Container';
    import { Button } from '@material-ui/core';
    import { logout } from "../../features/userSlice";
    import { NavLink } from 'react-router-dom';
    import { useDispatch } from 'react-redux';
    import useLogOut from '../auth/Logout';

    function LoginUser()
    {
    const user = useSelector(selectUser);
    // use hook at component body extracting logoutUser method
    const { logoutUser } = useLogOut();

    const dispatch = useDispatch();

    const handleLogout = (e) =>
    {
    if(e) e.preventDefault();

    dispatch(logout());
    };

    const UserLoggedInAlert = () =>
    {
    return <Container>
    <span>
    You are already logged in!
    </span>
    <Button
    component={NavLink}
    variant="contained"
    color="primary"
    to="/logout"
    // here now you can save logout user since no hooks are being called
    onClick={function(){ logoutUser(); handleLogout()}}
    >
    Do you want to logout?
    </Button>

    </Container>
    };

    return (
    <Container>
    {user ? <UserLoggedInAlert/> : <SignIn/> }
    </Container>
    );
    }
    export default LoginUser;
    Logout.js零件:
    import axiosInstance from '../../axios';
    import { useHistory } from 'react-router-dom';

    export default function useLogOut() {

    const history = useHistory();

    // we don't useEffect here, we are only interested in function logoutUser

    const logoutUser = () => {
    const response = axiosInstance.post('user/logout/blacklist/', {
    refresh_token: localStorage.getItem('refresh_token'),
    });
    localStorage.removeItem('access_token');
    localStorage.removeItem('refresh_token');
    axiosInstance.defaults.headers['Authorization'] = null;
    history.push('/login');
    }

    return { logoutUser }
    };
    我的 index.js:
    import useLogOut from './components/auth/Logout';


    const routing = (
    <Router>
    <Route path="/logout" component={useLogOut} />
    </Router>
    );

    ReactDOM.render(routing, document.getElementById('root'));
    既然我已经改变了它,这将是我的索引路由器的正确路径吗?
    新错误:
    Error: Objects are not valid as a React child (found: object with keys {logoutUser}). If you meant to render a collection of children, use an array instead.

    最佳答案

    当您调用 LogoutonClick你正在从你的函数中调用钩子(Hook) Logout在组件主体之外,什么是不允许的。
    您可以将 Logout 逻辑抽象为自定义 Hook ,在该 Hook 中返回 logoutUser功能:

    export default function useLogOut() {

    const history = useHistory();

    // we don't useEffect here, we are only interested in function logoutUser

    const logoutUser = () => {
    const response = axiosInstance.post('user/logout/blacklist/', {
    refresh_token: localStorage.getItem('refresh_token'),
    });
    localStorage.removeItem('access_token');
    localStorage.removeItem('refresh_token');
    axiosInstance.defaults.headers['Authorization'] = null;
    history.push('/login');
    }

    return { logoutUser }
    };
    然后你在你的 LoginUser 使用你的自定义钩子(Hook)组件主体,提取 logoutUser方法:
    function LoginUser()
    {
    const user = useSelector(selectUser);
    // use hook at component body extracting logoutUser method
    const { logoutUser } = useLogOut();

    const dispatch = useDispatch();

    const handleLogout = (e) =>
    {
    if(e) e.preventDefault();

    dispatch(logout());
    };

    const UserLoggedInAlert = () =>
    {
    return <Container>
    <span>
    You are already logged in!
    </span>
    <Button
    component={NavLink}
    variant="contained"
    color="primary"
    to="/logout"
    // here now you can safely logout user since no hooks are being called
    onClick={function(){ handleLogout(); logoutUser()}}
    >
    Do you want to logout?
    </Button>

    </Container>
    };

    return (
    <Container>
    {user ? <UserLoggedInAlert/> : <SignIn/> }
    </Container>
    );
    }
    export default LoginUser;
    您可以领先一步,简化您的 LogOut零件:
    export default function LogOut() {

    const { logoutUser } = useLogOut();

    useEffect(() => {
    logoutUser()
    });
    return <div>Logout</div>;
    };
    编辑
    为简单起见,您的 Logout.js 执行以下操作:
    export const useLogOut = () => {

    const history = useHistory();

    // we don't useEffect here, we are only interested in function logoutUser

    const logoutUser = () => {
    const response = axiosInstance.post('user/logout/blacklist/', {
    refresh_token: localStorage.getItem('refresh_token'),
    });
    localStorage.removeItem('access_token');
    localStorage.removeItem('refresh_token');
    axiosInstance.defaults.headers['Authorization'] = null;
    history.push('/login');
    }

    return { logoutUser }
    };

    export default function LogOut() {

    const { logoutUser } = useLogOut();

    useEffect(() => {
    logoutUser()
    });
    return <div>Logout</div>;
    };
    在您的登录处,您使用大括号导入钩子(Hook):
    import { useLogOut } from '../auth/Logout';
    并在没有大括号的 index.js 处导入组件:
    import LogOut from './components/auth/Logout';


    const routing = (
    <Router>
    <Route path="/logout" component={LogOut} />
    </Router>
    );

    关于javascript - React - 错误 : Invalid hook call. Hooks 只能在函数组件的主体内部调用。我的语法有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66056529/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com