我尝试提交一个登录页面,在请求处理过程中,登录表单被禁用。如果我提交了不正确的凭据,表单会按预期禁用,请求会被发送,一旦返回401,表单会再次启用。但是如果我尝试使用不同的凭据再次提交,axios请求会挂起。而且承诺永远不会解决。我的浏览器标签挂起,我不得不关闭它。
下面是登录页面的代码:
import React, { useState } from 'react';
import { useNavigate, NavigateFunction } from 'react-router-dom';
import { MailOutlined, KeyOutlined } from '@ant-design/icons';
import { Button, Form, Input, Typography } from 'antd';
import Navbar from '../components/Navbar';
import { DASHBOARD_ROUTE } from '../data/constants';
import styles from './Login.module.css';
import axios from 'axios';
export interface LoginProps {}
interface LoginCredentials {
usernameOrEmail: string,
password: string,
}
const { Title } = Typography;
// login page
const Login = (props: LoginProps): JSX.Element | null => {
const [passwordVisible, setPasswordVisible] = useState<boolean>(false);
const [loginDisabled, setLoginDisabled] = useState<boolean>(false);
const navigate: NavigateFunction = useNavigate();
const handleLogin = (credentials: LoginCredentials): void => {
if (loginDisabled) {
return;
}
setLoginDisabled(true);
axios.post(
'/accounts/jwt/create/',
{
username: credentials.usernameOrEmail,
password: credentials.password
},
{
baseURL: 'http://localhost:8000',
headers: {
'Content-Type': 'application/json'
}
}
).then(() => navigate(DASHBOARD_ROUTE)
).catch((err: any) => {
console.log(err);
setLoginDisabled(false);
});
};
return (
<div>
<Navbar selectedKey='login'>
<div className={styles.mainContainer}>
<Title>Login</Title>
<Form
name='basic'
layout={'vertical'}
initialValues={{ remember: true }}
onFinish={handleLogin}
disabled={loginDisabled}
>
<Form.Item
label='Username/Email'
name='usernameOrEmail'
rules={[{ required: true, message: 'Please enter your username/email' }]}
>
<Input
name="usernameOrEmail"
placeholder='Enter username/email'
prefix={<MailOutlined />}
/>
</Form.Item>
<Form.Item
label='Password'
name='password'
rules={[{ required: true, message: 'Please enter your password' }]}
>
<Input.Password
name="password"
placeholder='Enter password'
prefix={<KeyOutlined />}
visibilityToggle={{ visible: passwordVisible, onVisibleChange: setPasswordVisible }}
/>
</Form.Item>
<Form.Item wrapperCol={{ offset: 8, span: 16 }}>
<Button
type='primary'
htmlType='submit'
>
Login
</Button>
</Form.Item>
</Form>
</div>
</Navbar>
</div>
);
}
export default Login;
我期望的工作方式是,在handleLogin
发送请求之前,loginDisabled
钩子将被设置为true,这将把表单的disabled
属性设置为true
,然后,axios请求将被发送,一旦请求返回,loginDisabled
将被再次设置为false,这样表单将再次可用。
不知何故,如果我尝试登录两次,UI就会冻结,axios请求永远不会完成。我可以在后端看到请求通过并得到响应,axios请求拦截器被触发,但axios * 响应 * 拦截器从未被触发。我知道通常情况下我应该有一个超时,但这不应该发生在任何地方。我想我把钩子的某个地方搞砸了。
我收集了一些东西:
- 后端工作正常,事实上,不管axios在哪里发送请求,它总是冻结
- 如果我删除
setLoginDisabled
函数调用,整个问题就完全消失了。当然,这意味着表单永远不会被禁用。
你知道这是怎么回事吗?任何形式的帮助都很感激,谢谢!
1条答案
按热度按时间1cosmwyk1#
弄明白了是怎么回事:
Navbar
组件实际上还依赖于用户的身份验证状态,这在某些地方会导致无限循环。2删除(或者说重构)Navbar
对我来说就是这样。