Question :
the complexity inside the .map function is so high, any suggestions about reorganizing the code to map the routes and apply protection to them at the same time? i tried adding the routes inside an array so I can loop through them, my code is working perfectly but I'm searching for a better approach since this look so complex and wrong
This is my Routes config file
import Login from '../Pages/Auth/Login';
import Register from '../Pages/Auth/Register';
import Home from '../Pages/Home/Home';
const routes = [
{
path: '/',
component: <Home />,
protected: false,
},
{
path: '/login',
component: <Login />,
protected: false,
},
{
path: '/register',
component: <Register />,
protected: false,
},
];
export default routes;
this is my App.js file
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import { isLoggedIn } from './redux/slices/auth';
import './App.css';
import Layout from './Layouts/Layout';
import routes from './config/routes';
function App() {
const dispatch = useDispatch();
const user = useSelector((state) => state.user);
useEffect(() => {
dispatch(isLoggedIn());
}, []);
return (
<>
<BrowserRouter>
<Layout>
<Routes>
{routes.map((route, i) => (
<>
{route.path === '/' ? (<Route key={i} exact path={route.path} element={route.component} />) : ((user && route.protected && <Route key={i} path={route.path} element={route.component} />) || (!user && !route.protected && <Route key={i} path={route.path} element={route.component} />))}
</>
))}
</Routes>
</Layout>
</BrowserRouter>
</>
);
}
export default App;
CodePudding user response:
react-router-dom
is already very good and the rendering of the routes, and this isn't something you need to reinvent the wheel for. I'd suggest creating a PrivateRoutes
layout route component (see this post for implementation details) and reconfigure your routes declaration so it can be directly passed to the useRoutes
hook that returns an object to be directly rendered.
Example:
import Login from '../Pages/Auth/Login';
import Register from '../Pages/Auth/Register';
import Home from '../Pages/Home/Home';
...
import PrivateRoutes from '../components/PrivateRoutes';
const routesConfig = [
{
path: '/',
element: <Home />,
},
{
path: '/login',
element: <Login />,
},
{
path: '/register',
element: <Register />,
},
{
element: <PrivateRoutes />, // <-- checks auth status
children: [
{
path: "/dashboard",
element: <Dashboard />,
},
{
path: "/profile",
element: <Profile />,
},
... other protected routes ...
],
},
... other unprotected routes ...
];
export default routesConfig;
...
import { useRoutes } from 'react-router-dom';
import { isLoggedIn } from './redux/slices/auth';
import './App.css';
import Layout from './Layouts/Layout';
import routesConfig from './config/routes';
function App() {
const routes = useRoutes(routesConfig);
const dispatch = useDispatch();
useEffect(() => {
dispatch(isLoggedIn());
}, []);
return (
<Layout>
{routes}
</Layout>
);
}
Wrap App
with the BrowserRouter
so the useRoutes
hook can be used in App
.
import { BrowserRouter } from 'react-router-dom';
...
return (
<BrowserRouter>
<App />
</BrowserRouter>
);