I'm a bit new to two-sided applications (and to React). I'm currently building an application that has both a "user" and a "business" side, and the type of user is decided after the user authenticates themselves. For that, my current approach is to simply create multiple versions of routers, and depending on the redux state for the user's type, I am dynamically loading in a different router. In the case that a user isn't authenticated, I am making use of a "generic" default router. Once the user logs in, the router is then switched to the appropriate one under App.js
I am wondering if there is a better way to do this, particularly because after a user authenticates themselves, there is a significant delay (a couple of seconds) in the router being switched in the background. For example, the route "/" goes to the landing page react component for the "generic" router, but goes to the dashboard page for the "user" router. Once the user logs in, I redirect them to the "/" router to move them to the dashboard page, however there is a weird delay and the user is actually taken back to the landing page for a few seconds, then the page re-builds to the proper user dashboard that is expected at the "/" route for an authenticated user.
Here is the code for the different types of routers:
export function UserRouter() {
return useRoutes([
{
path: '/learn',
element: <DashboardLayout />,
children: [
{ path: ':id', element: <Learn />},
]
},
{
path: '/dashboard',
element: <DashboardLayout />,
children: [
{ path: 'overview', element: <Overview /> },
{ path: 'tasks', element: <Tasks /> },
{ path: 'community', element: <Community /> },
{ path: 'announcements', element: <Announcements /> },
],
},
{ path: '/companies',
element: <DashboardLayout />,
children: [
{ path: ':id', element: <Company />},
]
},
{
path: '/termDocuments',
element: <EmptyPage />,
children: [
{ path: ':embedURL', element: <AirtableEmbedPage />},
]
},
{
path: '/',
element: <LogoOnlyLayout />,
children: [
{ path: '/', element: <Navigate to="/dashboard/overview" /> },
{ path: 'login', element: <Login /> },
{ path: 'register', element: <UserRegister /> },
{ path: 'landing', element: <Landing />},
{ path: '404', element: <NotFound /> },
{ path: '*', element: <Navigate to="/404" /> },
],
},
{ path: '*', element: <Navigate to="/404" replace /> },
]);
}
export function BusinessRouter() {
return useRoutes([
{
path: '/dashboard',
element: <DashboardLayout />,
children: [
{ path: 'overview', element: <BusinessOverview /> },
{ path: 'home', element: <BusinessHomePage /> },
{ path: 'community', element: <BusinessCommunity /> },
{ path: 'announcements', element: <BusinessAnnouncements /> },
],
},
{ path: '/companies',
element: <DashboardLayout />,
children: [
{ path: ':id', element: <Company />},
]
},
{
path: '/termDocuments',
element: <EmptyPage />,
children: [
{ path: ':embedURL', element: <AirtableEmbedPage />},
]
},
{
path: '/',
element: <LogoOnlyLayout />,
children: [
{ path: '/', element: <Navigate to="/dashboard/overview" /> },
{ path: 'login', element: <BusinessLogin /> },
{ path: 'register', element: <UserRegister /> },
{ path: 'landing', element: <Landing />},
{ path: '404', element: <NotFound /> },
{ path: '*', element: <Navigate to="/404" /> },
],
},
{
path: '/business',
element: <DashboardLayout />,
children: [
{ path: 'app', element: <Overview />}
],
},
{ path: '*', element: <Navigate to="/404" replace /> },
]);
}
export function GenericRouter() {
return useRoutes([
{
path: '/',
element: <LogoOnlyLayout/>,
children: [
{path: '/', element: <Landing/>},
{path: '404', element: <NotFound/>},
{path: 'founder', element: <Founders/>},
{path: '*', element: <Navigate to="/"/>},
// {path: '*', element: <Navigate to="/404"/>},
],
},
{
path: '/business',
element: <LogoOnlyLayout/>,
children: [
{path: 'login', element: <BusinessLogin/>},
{path: 'register', element: <UserRegister/>},
],
},
{
path: '/user',
element: <LogoOnlyLayout/>,
children: [
{path: 'login', element: <Login/>},
{path: 'register', element: <UserRegister/>},
],
},
{path: '*', element: <Navigate to="/" replace/>},
// {path: '*', element: <Navigate to="/404" replace/>},
]);
}
And here is the actual switching of the router based off of a redux variable that is updated in the background (within App.js)
const selectRouter = (userType) => {
switch (userType) {
case USER:
return <UserRouter/>
case BUSINESS:
return <BusinessRouter/>
default:
return <GenericRouter/>
}
}
function RouterChoice() {
const userType = useSelector(state => state.auth?.userType)
return selectRouter(userType)
}
export default function App() {
return (
<StylesProvider injectFirst>
<ThemeProvider>
<ScrollToTop />
<BaseOptionChartStyle />
<RouterChoice />
</ThemeProvider>
</StylesProvider>
);
}
I am having a problem where children element of the route not displaying in the correct URL as example like if my URL is http://localhost:3000/dash by default it will go to http://localhost:3000/dash/default. I even already put the component in the children element. I am trying to wrap the children element with DashboardLayout and render its children inside DashboardLayout. I dont get a clue on this problem.
Below are code from the file
routes.js
export const routes = [
{
path: "dash",
element: <DashboardLayout />,
children: [
{
path: "*",
elment: <Navigate to={"/dash/default"} />,
},
{
path: "",
element: <Navigate to={"/dash/default"} />,
},
{
path: "default",
element: <Home />,
},
],
},
{
path: "*",
children: [
{
path: "*",
element: <Home />
},
],
},
];
Dashboardlayout.js
const DashboardLayout = ({ children }) => {
<React.Fragment>
<div>{children}</div>
</React.Fragment>;
};
export default DashboardLayout;
I am quite new to React, and I have a project that uses react-location
I would like to load some routes lazily only if the path is activated.
My current config is:
my base routing module
export const routes: Route[] = [
...HomeModuleRoutes, // I want this to be instantly loaded.
...LazyRoutes, // I want this to be lazy loaded.
{ path: '/', element: <Navigate to="/home" /> },
];
those 2 constants look like this :
home.routing.ts
export const routes: Route[] = [
{
path: 'home',
element: <HomeTemplate />,
children: [
{
path: '/',
element: <HomePage />,
},
],
},
];
lazy.routing.ts
export const LazyRoutes: Route[] = [
{
path: 'test',
element: <LazyTemplate />,
children: [
{
path: '/',
element: <LazyList />,
},
{
path: 'add',
element: <LazyAdd />,
},
{
path: 'detail',
element: <LazyDetail />,
},
],
},
];
I don't quite see documentation or an example on this, is it just wrapping the component with <Suspense>?
You should import your component with React.lazy like:
const HomeTemplate = React.lazy(() => import("./HomeTemplate "));
check this example for react-router v6 lazy loading
I download a MUI template for a React web-base app.
In Routes.js file, I commented out a line
and deleted the "," before this line. Later I uncomment the line and add the ",", so it looks the same as before; however, there is an issue as follows: when npm start, it fails to compile.
I'm beginner for reactjs and can't understand what this means.
src\App.js
Line 2:20: Parse errors in imported module './routes': Unexpected token, expected "," (26:8) (26:8) import/no-named-as-default
Line 2:20: Parse errors in imported module './routes': Unexpected token, expected "," (26:8) (26:8) import/no-named-as-default-member
src\routes.js
Line 24:52: Delete `,` prettier/prettier
Line 36:55: Delete `,` prettier/prettier
Search for the keywords to learn more about each error.
routes.js is as follows:
import { Navigate, useRoutes } from 'react-router-dom';
// layouts
import DashboardLayout from './layouts/dashboard';
import LogoOnlyLayout from './layouts/LogoOnlyLayout';
//
import Login from './pages/Login';
import Register from './pages/Register';
import DashboardApp from './pages/DashboardApp';
import Products from './pages/Products';
import Blog from './pages/Blog';
import User from './pages/User';
import NotFound from './pages/Page404';
// ----------------------------------------------------------------------
export default function Router() {
return useRoutes([
{
path: '/dashboard',
element: <DashboardLayout />,
children: [
{ element: <Navigate to="/dashboard/app" replace /> },
{ path: 'app', element: <DashboardApp /> },
{ path: 'user', element: <User /> },
{ path: 'products', element: <Products /> },
// { path: 'blog', element: <Blog /> },
]
},
{
path: '/',
element: <LogoOnlyLayout />,
children: [
{ path: 'login', element: <Login /> },
{ path: 'register', element: <Register /> },
{ path: '404', element: <NotFound /> },
{ path: '/', element: <Navigate to="/dashboard" /> },
{ path: '*', element: <Navigate to="/404" /> },
]
},
{ path: '*', element: <Navigate to="/404" replace /> }
]);
}
I fixed this question by adding two lines in .eslintrc file
"import/no-named-as-default": 0,
"import/no-named-as-default-member": 0,
that means, I unactive that two rules so no compliling error will be caused by these two rules
I am using redux for one of my component. In mapStateToProps I like to use the id of the URL Params, but in no ways I am able to get the id of the url in that function.
function mapStateToProps(state, ownProps) {
**const recId = ownProps.id;**
const reconciliationRule =
recId && state.reconciliationRules.length > 0
? getReconciliationById(state.reconciliationRules, recId)
: newReconciliationRule;
return {
reconciliationRule,
reconciliationRules: state.reconciliationRules,
};
My route.js looks like below
const routes = [
{
path: "app",
element: <DashboardLayout />,
children: [
{ path: "dashboard", element: <DashboardComponent /> },
{ path: "reconciliations", element: <ReconciliationComponent /> },
***{ path: "reconciliationRule/:id", element: <RulesComponent /> },***
{ path: "help", element: <HelpComponent /> },
{ path: "reports", element: <ReportComponent /> },
{ path: "settings", element: <SettingsComponent /> },
{ path: "billing", element: <BillingComponent /> },
{ path: "*", element: <Navigate to="/404" /> },
],
}
]
See if you see I want to send { path: "reconciliationRule/:id", element: } into RulesComponent
Static props I can send easily e.g.
{ path: "reconciliationRule/:id", element: <RulesComponent staticId={1}/> }
I can access this in mapStateToProps, but question is how to pass an ID of URL in react-router-dom.
Tried lot of permutation and combination but unable to solve it.
Don't want to switch to rr5 or rr4 where I can do this using rendering, but I need this to be done rr6.
Any help in this regards will be appreciated.