React: how to declare routes inside a component? - javascript

First off, I tried searching for this issue before I posted but couldn't find a solution for a similar use case.
So I have a component called App.js where I define all my top level routes:
<TransitionGroup>
<CSSTransition key={location.key} mountOnEnter={true} unMountOnExit={true} timeout={800} classNames="fade-up-down">
<Switch location={location}>
<Route exact path="/" component={Home} />
<Route exact path="/about" component={About} />
<Route exact path="/artists" component={Artists} />
<Route path="/artworks/:slug" component={Artwork} />
</Switch>
</CSSTransition>
</TransitionGroup>
Now, inside the home component, I want to have my second level of routes, which I didn't do in App.js because I had props to pass from Home.js to the child components. The routes portion in my Home.js looks like this:
<Switch>
<Route exact path="/" render={(props) => <Map {...props} artworks={artworks} />} />
<Route exact path="/grid" render={(props) => <Grid {...props} artworks={artworks} />} />
<Route exact path="/rainbow" render={(props) => <Rainbow {...props} artworks={artworks} />} />
</Switch>
The second level routes inside Home.js work fine, but when I try to go to any of the other top level routes, eg. /artists/ or /about, they do not work.
Can someone please point me to the right direction here? Thanks!

I don't think is it possible the way you want.
I think you are overriding the App Router when you navigate to you Home component.
Your routes has to be on a top lvl of your App

Moving the routes after the first one from to the top worked. Here's how it looks now:
<TransitionGroup>
<CSSTransition key={location.key} mountOnEnter={true} unMountOnExit={true} timeout={800} classNames="fade-up-down">
<Switch location={location}>
<Route exact path="/about" component={About} />
<Route exact path="/artists" component={Artists} />
<Route path="/artworks/:slug" component={Artwork} />
<Route path="/" component={Home} />
</Switch>
</CSSTransition>
</TransitionGroup>

Related

How to restrict routes in another layout react router v6

I am having three layouts and they are Admin, App, CompanySetup. I need to restrict routes of app layout in admin layout and vice-versa. I shared my Code below.
Routes.js
<Route path='/'>
<Route path='app'>
<Route index element={<Home />}></Route>
<Route
path='search/category/:category'
element={<SearchPage />}
></Route>
<Route
path='search/category/:category/name/:name'
element={<SearchPage />}
></Route>
</Route>
<Route path='admin'>
<Route element={<AdminRouteProvider></AdminRouteProvider>}>
<Route
path='dashboard'
element={<AdminDashboard />}
></Route>
</Route>
</Route>
</Route>
AppLayout.js
<Layout className='min-vh-100 bg-white'>
<Content className='p-4'>
<Outlet />
</Content>
</Layout>
AdminLayout.js
<Layout className='min-vh-100 bg-white'>
<Sider width={240} className='bg-white border-end'>
<Sidebar />
</Sider>
<Layout>
<Header className='bg-body border-bottom'>
<HeaderNav></HeaderNav>
</Header>
<Content className='p-5 bg-body'>
<AdminRouteProvider>
<Outlet></Outlet>
</AdminRouteProvider>
</Content>
</Layout>
</Layout>
Here I am having separate layouts for '/app' and '/admin'. My issue is in admin layout '/app' is allowed. How to restrict that?
you can use useEffect/useEffectLayout to prevent from access the route or path of '/app'.
for example-
useEffect(()=>{
if(!JSON.parse(localStorage.getItem('admin')){
window.location.href="/app"
}
},[])
this is just an example may this code also change according to your need. If you still facing issue just lemme know.
From what I can tell you are not rendering any actual layout routes for either "/app" or "/admin". Import AppLayout and AdminLayout1 and render the appropriate layout routes.
import AppLayout from '../path/to/AppLayout';
import AdminLayout from '../path/to/AdminLayout';
...
<Route path="/">
<Route path="app" element={<AppLayout />}>
<Route index element={<Home />} />
<Route path="search/category/:category">
<Route index element={<SearchPage />} />
<Route path="name/:name" element={<SearchPage />} />
</Route>
</Route>
<Route path="admin" element={<AdminLayout />}>
<Route path="dashboard" element={<AdminDashboard />} />
<Route path="*" element={<Navigate to="dashboard" replace />} />
</Route>
</Route>

Nested routes content not showing up content

Below code is the entry point
<React.StrictMode>
<AppProvider>
<BrowserRouter>
<Routes>
<Route path='/admin/*' element={<Admin />} />
<Route path='*' element={<App />} />
</Routes>
</BrowserRouter>
</AppProvider>
</React.StrictMode>
I have Child routes under App.js and Admin.js, but routes under Admin is not routing as expected at the same time App.js routes are working accordingly.
Code for Admin.js is below
<div>
<ASideMenuNav />
<Routes>
<Route path='/admin/product' element={<AProductsInfo />} />
<Route path='/admin/offers' element={<AProductOffers />} />
</Routes>
</div>
Output is as shown below
enter image description here
Problem I am facing here is that when I click on any navigation menu its URL is changing but the content of the particular React component is not showing up.
Someone please tell me what am I missing. Is there something wrong with coding logic?
Descendent routes in the Routes component will have their paths built relative to the parent route. If the parent route path is "/admin/*" then the current paths are "/admin/admin/product" and "/admin/admin/offers". The solution is to remove the "/admin" path prefix on the descendent routes.
<div>
<ASideMenuNav />
<Routes>
<Route path="/product" element={<AProductsInfo />} />
<Route path="/offers" element={<AProductOffers />} />
</Routes>
</div>
Alternatively the Admin component could render an Outlet component and the routes could be converted to nested routes in the App.
<div>
<ASideMenuNav />
<Outlet />
</div>
<React.StrictMode>
<AppProvider>
<BrowserRouter>
<Routes>
<Route path='/admin' element={<Admin />}>
<Route path="product" element={<AProductsInfo />} />
<Route path="offers" element={<AProductOffers />} />
</Route>
<Route path='*' element={<App />}/>
</Routes>
</BrowserRouter>
</AppProvider>
</React.StrictMode>

How to render 404 page outside main layout

I am using react-router#6, and want to add a route for 404 pages, and render the page outside the main layout. This is what I have so far:
<BrowserRouter>
<Routes>
<Route path='/' element={<Layout />}>
<Route
path='/'
element={<HomePage />}
/>
<Route
path='login'
element={<LoginPage />}
/>
</Route>
<Route
path='*'
element={<PageNotFound />}
/>
</Routes>
</BrowserRouter>
The "*" route works fine, PageNotFound component is rendering outside the layout, as it should. Problem is that the any of the other routes does not show up, only the layout.
What am I missing?
From what you describe it sounds like the Layout component is missing rendering an Outlet component for the nested routes to render their content into.
Example:
import { Outlet } from 'react-router-dom';
const Layout = () => {
...
return (
<>
... common layout UI ...
<Outlet /> // <-- nested routes render out here
</>
);
};
<BrowserRouter>
<Routes>
<Route element={<Layout />}>
<Route path='/' element={<HomePage />} />
<Route path='login' element={<LoginPage />} />
</Route>
<Route path='*' element={<PageNotFound />} />
</Routes>
</BrowserRouter>
For more details you can see the following:
Layout Routes
Outlets

React Router 4 - Different Layouts?

I know this is been asked a few times, but nothing really seemed to apply to me.
I have this
App.js
<React.Fragment>
<Switch>
<Route path="/members" component={MemberAreaComponent} />
<Route exact path="/" component={NonMemberAreaComponent} />
<Route component={NotFoundComponent} />
</Switch>
</React.Fragment >
In members area component I have
// other html above here
<div className="main-area">
<main>
<Switch>
<Route path="/members/home" component={HomeComponent} />
</Switch>
</main>
</div>
NonMemberAreaComponent
<div className="non-members-area-container">
<Route path="/login" component={LoginComponent} />
<Route path="/" component={NonMemberHomeComponent} />
</div>
When I try to do /Login I keep getting my "NotFoundComponent". I think it is "exact" what is messing everything up.
Your second Route only matches when the path is exactly /. Remove the exact prop to make it active when / is just a part of the path.
<React.Fragment>
<Switch>
<Route path="/members" component={MemberAreaComponent} />
<Route path="/" component={NonMemberAreaComponent} />
<Route component={NotFoundComponent} />
</Switch>
</React.Fragment>

React router v4 ignores exact

I'm trying to render NotFound component or redirect to root route using React router v4 when path is incorrect, but when I'm on "/" my app renders 2 components.
<Switch>
<Navbar>
<Route exact path="/" component={App} />
<Route path="/Other" component={Other} />
<Route component={NotFound} />
</Navbar>
</Switch>
and my Navbar looks like:
render()
{
return(
<div>
{/*Any content here*/}
{this.props.children}
</div>
);
}
If I replace <Route component={NotFound} /> to <Redirect to="/" /> it looks working, but I'm getting an error: Warning: You tried to redirect to the same route you're currently on: "/"
Thanks for your help! :)
The placement of your Switch component is incorrect, it should wrap the components children where Routes are defined
<Navbar>
<Switch>
<Route exact path="/" component={App} />
<Route path="/Other" component={Other} />
<Route component={NotFound} />
</Switch>
</Navbar>

Categories

Resources