英文:
React redirects to the login page after entering username and password instead of redirecting to the required page
问题
I'm creating a simple react application with 3 user roles. On the login page localhost:3000/login
I have fields for username
and password
. Once those details are entered and the login button is clicked, the data is sent to the backend (running node js) and that data is used to query a MySql database. If the entered data matches a user in the database, the userId
, name
, password
, and role
is sent to the backend. This data is then sent to the front end. I can read the retrieved data from the front end and up to this point it works fine. However, when I'm trying to redirect a user according to the role, say the role is doctor and I want to redirect the user to localhost:3000/doctor
, it goes to localhost:3000/doctor
momentarily and switches to localhost:3000/login?
. Shown below is the code for the login component.
import { useState } from "react";
import Axios from 'axios';
import { useNavigate } from 'react-router-dom';
import './login.css';
const Login = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
let navigate = useNavigate();
const handleLogin = () => {
Axios.post("http://localhost:3001/login",
{
email: email,
password: password,
},
{
headers: {
'Content-Type': 'application/json'
}
}
)
.then((response) => {
console.log('response 1', response.data[0]['role']);
if (response.data[0]['role'] === 'doctor') {
navigate('/doctor');
}
});
};
return (
<div>
<form>
<h3>Electronic Prescription System</h3>
<h3>Login</h3>
<label>Email Address</label>
<input
className="inputs"
type="text"
placeholder="email"
onChange={(e) => {
setEmail(e.target.value)
}}
/>
<label>Password</label>
<input
className="inputs"
type="password"
placeholder="password"
onChange={(e) => setPassword(e.target.value)}
/>
<button onClick={handleLogin}>Log in</button>
</form>
</div>
)
};
export default Login;
If I remove all the code inside the handleLogin
function and just have navigate('/doctor');
it redirects properly.
The routes are inside the Main component as shown below.
import React from 'react';
import { Routes, Route } from 'react-router-dom';
import Login from "./pages/Login/Login";
import Doctor from "./pages/Doctor/Doctor";
import Patient from "./pages/Patient/Patient";
import Pharmacy from "./pages/Pharmacy/Pharmacy";
const Main = () => {
return (
<Routes>
<Route path="login" element={<Login />} />
<Route path="doctor" element={<Doctor />} />
<Route path="patient" element={<Patient />} />
<Route path="pharmacy" element={<Pharmacy />} />
</Routes>
);
}
export default Main;
The Doctor
Component:
import { HeaderPanel } from '../../components/headerPanel/headerPanel';
import { PrescribePanel } from '../../components/prescribePanel/prescribePanel';
import { PrescriptionsList } from '../../components/prescriptionsList/prescriptionsList';
import './styles.css';
export const Doctor = () => {
return (
<>
<HeaderPanel />
<div className='wrapper'>
<PrescribePanel />
<PrescriptionsList />
</div>
</>
);
}
export default Doctor;
I'm using react-router-dom
version 6.6.1 and the react
version is 18.2.0.
Tried using a useEffect
hook to capture the role changing and redirecting, but it did not work either.
英文:
I'm creating a simple react application with 3 user roles. On the login page localhost:3000/login
I have fields for username
and password
. Once those details are entered and the login button is clicked, the data is sent to the backend (running node js) and that data is used to query a MySql database. If the entered data matches a user in the database, the userId
, name
, password
, and role
is sent to the backend. This data is then sent to the front end. I can read the retrieved data from the front end and up to this point it works fine. However, when I'm trying to redirect a user according to the role, say the role is doctor and I want to redirect the user to localhost:3000/doctor
, it goes to localhost:3000/doctor
momentarily and switches to localhost:3000/login?
. Shown below is the code for the login component.
import { useState } from "react";
import Axios from 'axios';
import { useNavigate } from 'react-router-dom'
import './login.css';
const Login = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
let navigate = useNavigate()
const handleLogin = () => {
Axios.post("http://localhost:3001/login",
{
email: email,
password: password,
},
{
headers: {
'Content-Type': 'application/json'
}
}
)
.then((response) => {
console.log('response 1', response.data[0]['role'])
if (response.data[0]['role'] === 'doctor') {
navigate('/doctor');
}
});
};
return (
<div>
<form>
<h3>Electronic Prescription System</h3>
<h3>Login</h3>
<label>Email Address</label>
<input
className="inputs"
type="text"
placeholder="email"
onChange={(e) => {
setEmail(e.target.value)
}}
/>
<label>Password</label>
<input
className="inputs"
type="password"
placeholder="password"
onChange={(e) => setPassword(e.target.value)}
/>
<button onClick={handleLogin}>Log in</button>
</form>
</div>
)
};
export default Login;
If I remove all the code inside the handleLogin
function and just have navigate('/doctor');
it redirects properly.
The routes are inside the Main component as shown below.
import React from 'react';
import { Routes, Route } from 'react-router-dom';
import Login from "./pages/Login/Login";
import Doctor from "./pages/Doctor/Doctor";
import Patient from "./pages/Patient/Patient";
import Pharmacy from "./pages/Pharmacy/Pharmacy";
const Main = () => {
return (
<Routes>
<Route path="login" element={<Login />} />
<Route path="doctor" element={<Doctor />} />
<Route path="patient" element={<Patient />} />
<Route path="pharmacy" element={<Pharmacy />} />
</Routes>
);
}
export default Main;
The Doctor
Component:
import { HeaderPanel } from '../../components/headerPanel/headerPanel'
import { PrescribePanel } from '../../components/prescribePanel/prescribePanel'
import { PrescriptionsList } from '../../components/prescriptionsList/prescriptionsList'
import './styles.css';
export const Doctor = () => {
return (
<>
<HeaderPanel />
<div className='wrapper'>
<PrescribePanel />
<PrescriptionsList />
</div>
</>
);
}
export default Doctor
I'm using react-router-dom
version 6.6.1 and the react
version is 18.2.0.
Tried using a useEffect
hook to capture the role changing and redirecting, but id did not work either.
答案1
得分: 1
我怀疑的情况是,“登录”按钮正在提交表单,该表单采用默认的表单操作并重新加载页面,当前路由路径为“/login”。默认情况下,button
元素的 type="submit"
属性值。
要解决这个问题,我建议将 handleLogin
附加到 form
元素的 onSubmit
事件处理程序,并在 onSubmit
事件对象上调用 preventDefault
以防止提交表单和重新加载页面。这应该允许身份验证逻辑按预期完成。
请养成具体指定 button
元素的 type
属性的习惯。
const Login = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const navigate = useNavigate();
const handleLogin = (e) => { // <-- onSubmit 事件对象
e.preventDefault(); // <-- 不执行表单操作
Axios.post(
"http://localhost:3001/login",
{ email, password },
{
headers: {
'Content-Type': 'application/json'
}
}
)
.then((response) => {
if (response.data[0]['role'] === 'doctor') {
navigate('/doctor');
}
});
};
return (
<div>
<form onSubmit={handleLogin}> // <-- form onSubmit 事件处理程序
<h3>电子处方系统</h3>
<h3>登录</h3>
<label>
电子邮件地址
<input
className="inputs"
type="text"
placeholder="email"
onChange={(e) => setEmail(e.target.value)}
/>
</label>
<label>
密码
<input
className="inputs"
type="password"
placeholder="password"
onChange={(e) => setPassword(e.target.value)}
/>
</label>
<button type="submit"> // <-- 具体指定按钮类型
登录
</button>
</form>
</div>
);
};
export default Login;
注意:以上是你要翻译的内容。
英文:
What I suspect is happening here is that the "log in" button
is submitting the form which takes the default form action and reloads the page, the current route path being "/login"
. button
elements have a type="submit"
attribute value by default.
To resolve I'd suggest attaching handleLogin
to the form
element's onSubmit
event handler and calling preventDefault
on the onSubmit
event object to prevent submitting the form and prevent reloading the page. This should allow the authentication logic to complete as expected.
Try to get yourself in the habit of being specific with the button
element's type
attribute.
const Login = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const navigate = useNavigate();
const handleLogin = (e) => { // <-- onSubmit event object
e.preventDefault(); // <-- don't take form action
Axios.post(
"http://localhost:3001/login",
{ email, password },
{
headers: {
'Content-Type': 'application/json'
}
}
)
.then((response) => {
if (response.data[0]['role'] === 'doctor') {
navigate('/doctor');
}
});
};
return (
<div>
<form onSubmit={handleLogin}> // <-- form onSubmit event handler
<h3>Electronic Prescription System</h3>
<h3>Login</h3>
<label>
Email Address
<input
className="inputs"
type="text"
placeholder="email"
onChange={(e) => setEmail(e.target.value)}
/>
</label>
<label>
Password
<input
className="inputs"
type="password"
placeholder="password"
onChange={(e) => setPassword(e.target.value)}
/>
</label>
<button type="submit"> // <-- be specific with button type
Log in
</button>
</form>
</div>
);
};
export default Login;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论