Home > Software design >  React redirects to the login page after entering username and password instead of redirecting to the
React redirects to the login page after entering username and password instead of redirecting to the

Time:01-09

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.

CodePudding user response:

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;
  • Related