my privateroute is not redirecting afetr condition is satisfied. in my case when admin click on login it has to check wether token is in localstorage if there is not token then it has to redirect to login page and if token is there it has to redirect to home page. but without toke when i try to access the home page it is redirecting to login page but after login it is not redirecting to home page. Here is my code.
App.js
import "./App.css";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import Login from "./pages/Login";
import Register from "./pages/Register";
import { PrivateRoute } from "./HOC/PrivateRoute";
function App() {
return (
<div className="App">
<Router>
<Routes>
<Route
path="/"
element={
<PrivateRoute>
<Home />
</PrivateRoute>
}
/>
<Route exact path="/login" element={<Login />} />
<Route exact path="/register" element={<Register />} />
</Routes>
</Router>
</div>
);
}
export default App;
PrivateRoute.js
import { Navigate } from "react-router-dom";
export function PrivateRoute({ children }) {
if (localStorage.getItem("token")) {
return children;
} else {
return <Navigate to="/login" replace />;
}
}
Login.js
import React, { useState } from "react";
import Layout from "../components/Layout/Layout";
import { Container, Form, Button, Row, Col } from "react-bootstrap";
import Input from "../components/UI/Input";
import { login } from "../redux/actions";
import { useDispatch, useSelector } from "react-redux";
import { Navigate } from "react-router-dom";
function Login(props) {
const [email, setEmail] = useState("");
const [userPassword, setUserPassword] = useState("");
const [error, setError] = useState("");
const auth = useSelector((state) => state.auth);
const dispatch = useDispatch();
const userLogin = (e) => {
e.preventDefault();
const user = {
email,
userPassword,
};
dispatch(login(user));
};
return (
<Layout>
<Container>
<Row style={{ marginTop: "100px" }}>
<Col md={{ span: 6, offset: 3 }}>
<Form onSubmit={userLogin}>
<Input
label="Email"
type="text"
placeholder="email"
valu={email}
onChange={(e) => setEmail(e.target.value)}
/>
<Input
label="Password"
type="password"
placeholder="Password"
valu={userPassword}
onChange={(e) => setUserPassword(e.target.value)}
/>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
</Col>
</Row>
</Container>
</Layout>
);
}
export default Login;
auth.actions.js
import axios from "../../helpers/axios";
import { authConstants } from "./constants";
export const login = (user) => {
console.log(user);
return async (dispatch) => {
dispatch({ type: authConstants.LOGIN_REQUEST });
const res = await axios.post("/auth/admin/login", { ...user });
console.log(res);
if (res.status === 200) {
const { accessToken, ...user } = res.data;
localStorage.setItem("token", accessToken);
dispatch({
type: authConstants.LOGIN_SUCCESS,
payload: { user, accessToken },
});
} else {
if (res.status === 400) {
dispatch({
type: authConstants.LOGIN_FAILURE,
payload: {
error: res.data.error,
},
});
}
}
};
};
auth.reducers.js
import { authConstants } from "../actions/constants";
const initialState = {
token: null,
user: {
firstName: "",
lastName: "",
email: "",
picture: "",
},
authenticate: false,
authenticating: false,
};
export default (state = initialState, action) => {
console.log(action);
switch (action.type) {
case authConstants.LOGIN_REQUEST:
state = {
...state,
authenticating: true,
};
break;
case authConstants.LOGIN_SUCCESS:
state = {
...state,
user: action.payload.user,
token: action.payload.accessToken,
authenticate: true,
authenticating: false,
};
}
return state;
};
Constants.js
export const authConstants = {
LOGIN_REQUEST: "LOGIN_REQUEST",
LOGIN_FAILURE: "LOGIN_FAILURE",
LOGIN_SUCCESS: "LOGIN_SUCCESS",
};
CodePudding user response:
Actually at the moment after user logged in, you don't navigate user from login page, you are just updating the localStorage without any redirect. You can navigate from login page like this:
function Login(props) {
...
const auth = useSelector((state) => state.auth);
...
if(auth.token){
return <Navigate to="/" replace />
}
return (<>login form</>)
}
You can also implement same logic by useEffect
hook, like below example:
import { useNavigate } from 'react-router-dom';
...
function Login(props) {
const {token} = useSelector((state) => state.auth);
const navigate = useNavigate();
...
useEffect(()=> {
if(token){
navigate('/');
}
}, [token])
...
return (<>login form</>)
}