I hope you are doing well!
I am trying out react-router-dom
v6 with the public and private routes and this is the code I currently have
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Login from "./user/pages/Login";
import { LoginRedirect } from "./auth/redirects/LoginRedirect";
import Home from "./shared/pages/Home";
import Authors from "./author/pages/Authors";
import Books from "./book/pages/Books";
import BookInformation from "./book/pages/BookInformation";
import CreateAuthor from "./author/pages/CreateAuthor";
import AuthorInformation from "./author/pages/AuthorInformation";
import { UserRoleRedirect } from "./auth/redirects/UserRoleRedirect";
import "./App.css";
function App() {
return (
<div className="App">
<BrowserRouter>
<Routes>
<Route path="login" element={<Login />} />
<Route path="/" element={<LoginRedirect />}>
<Route path="/" element={<Home />} />
<Route path="authors" element={<Authors />} />
<Route path="books" element={<Books />} />
<Route path="books/:bookId" element={<BookInformation />} />
</Route>
<Route path="/" element={<UserRoleRedirect />}>
<Route path="authors/new" element={<CreateAuthor />} />
<Route path="authors/:authorId" element={<AuthorInformation />} />
</Route>
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
and this is the code of my LoginRedirect
import React from "react";
import { useLocation, Navigate, Outlet } from "react-router-dom";
import { useAuth } from "../useAuth";
export const LoginRedirect = () => {
const { user } = useAuth();
const location = useLocation();
if (user.email === "" || user.email === null || user.email === undefined)
return <Navigate to="/login" state={{ from: location }} replace />;
return <Outlet />;
};
and my UserRoleRedirect
import React from "react";
import { useLocation, Navigate, Outlet } from "react-router-dom";
import { useAuth } from "../useAuth";
export const UserRoleRedirect = () => {
const { user } = useAuth();
const location = useLocation();
if (user.email === "" || user.email === null || user.email === undefined)
return <Navigate to="/login" state={{ from: location }} replace />;
if (user.roleType === "N")
return <Navigate to="/" state={{ from: location }} replace />;
return <Outlet />;
};
and my page is working fine; however, I want to make the login accessible only if the User is not logged in (I am not using any backend at the moment, I am only storing user values in redux for testing purposes) mostly because if I want to access '/books', I redirect the user to the login page if they are not logged in and on log in redirect them to the '/books' page. But if the User clicks the back button of the browser I want to return them to the Home page and not the log in page.
I tried wrapping the login route like the other routes and added a component that would test if logged in to redirect to the "/" path as follows
import React from "react";
import { useLocation, Navigate, Outlet } from "react-router-dom";
import { useAuth } from "../useAuth";
export const AuthenticationRedirect= () => {
const { user } = useAuth();
const location = useLocation();
if (user.email !== "" && user.email !== null && user.email !== undefined)
return <Outlet />;
return <Navigate to="/" state={{ from: location }} replace />;
};
but the component rerendered infinitely and didn't work.
I could add a test in the component
if(user.email!=="")
return <Navigate to="/" />
but I want to see if there is a way to manage it from the routes themselves.
How can I make the /login route only accessible if user not logged in?