I have an applications index page that lists all my applications. The index page is also the default route. I want to nest a 'applications new' modal in the index page. This way I can render the modal while on top of the index page. However, I'm not able to nest within the default route successfully.
Here's how I think it should work
<Route name='applications' path='/applications' handler={Applications}>
<DefaultRoute name="index" handler={ApplicationIndex}>
<Route name='applicationNew' path='/new' handler={ApplicationNewModal}/>
</DefaultRoute>
<Route name="applicationShow" path=':key' handler={ApplicationShow}/>
</Route>
When I try to transition to 'applicationNew' I get an error saying that no route was found with that name
You need to move it to its own Route inside a Route with handler={ApplicationIndex}.
<Route name='applications' path='/applications' handler={Applications}>
<DefaultRoute name="index" handler={ApplicationIndex} />
<Route handler={ApplicationIndex}>
<Route name='applicationNew' path='/new' handler={ApplicationNewModal} />
</Route>
<Route name="applicationShow" path=':key' handler={ApplicationShow}/>
</Route>
Related
I'm using react router v6 and I'm having trouble with correctly using index routes. I have the following top level routes which all work fine except navigating to "/".
<Routes>
<Route path="/" element={<DefaultPage />}>
<Route path="profile/*" element={<UserProfile account={true} />} />
<Route path="register/*" element={<UserProfile account={true} register={true} />} />
<Route path="user/:username/profile" element={<UserProfile />} />
{/*<Route path="account*" element={"Account"} />*/}
<Route path="feed/:slug/*" element={<StreamPage type="feed" />} />
<Route path="user/:slug/*" element={<StreamPage type="user" />} />
<Route path="post/edit" element={<PostEditorPage />} />
<Route path="post/edit/:id" element={<PostEditorPage />} />
<Route path="publication/edit" element={<PubEditorPage />} />
<Route path="publication/edit/:slug" element={<PubEditorPage />} />
<Route path="publication/:id" element={<PubPage />} />
<Route index element={<StreamPage index={true} />} />
</Route>
</Routes>
When I go to the root url <StreamPage index={true} /> renders as expected using the Outlet specified in DefaultPage but I get the following warning:
You rendered descendant <Routes> (or called useRoutes()) at "/" (under <Route path="">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.
Please change the parent <Route path=""> to <Route path="/*">."
This doesn't seem to happen with any of the other routes and when index is true StreamPage doesn't render any child routes so the problem has to be here but my code seems to resemble the examples from the docs pretty closely so I can't figure out what I'm doing wrong. Thoughts?
Note that the warning persists if I change the top line to
<Route path="/*" element={<DefaultPage />}>
For completness here is the relevant part of StreamPage
EDIT: Added the top Routes section thanks to help from comments identifying that there was a missing piece to generate the warning.
<Routes>
<Route index element={<StreamSidebar/> } />
<Route path="post/:subslug/*" element={<Sidebar/> }/>
</Routes>
{index && <Stream stream={stream} index={index} />}
{!index &&
<Routes>
<Route index element={<Stream stream={stream} index={index} />}/>
<Route path="post/:subslug/*" element={<PostPage stream={stream} />}/>
</Routes>}
(I can include the full thing if necessary but this is the only part with routes in it and even those shouldn't render when index is true)
}
#Drew Reese's responses answered the primary issue I was having with this code so I'm marking this as answered. What rule this code violates seemed different enough that I created a separate question that gives a really minimal example of how sibling nested index routes generate the warning and avoids all the confusion about what the heck all this other stuff is doing.
its maybe for use of /* in your route and if you will be deep in path of your route may cause of problem
I am designing a users dashboard in React, wherein User logs in and navigate to his dashboard with other links such as Archived, Profile and Settings. My Login and then Navigating to HomePage is working fine.
I have designed the Dashboard, Archived, Profile and Settings Page Links in Sidebar. Now when I am navigating to the Links. It takes me to a new URL path and my Sidebar disappears. I want my sidebar to still appear on all pages as long as I am logged in.
Below is my App.js where I have designed the upper level route:
return (
<div>
<Router history={history}>
<Switch>
<PrivateRoute exact path="/" component={HomePage} />
<Route path="/login" component={LoginPage} />
<Route path="/register" component={RegisterPage} />
<Redirect from="*" to="/" />
</Switch>
</Router>
</div>
);
Once User is on HomePage, I need the dashboard and other links to show. and when User clicks on any Sidebar link, Sidebar should still be there while the other page opens. So I added the inner Routes to the HomePage.jsx like this:
return (
<div>
<Router history={history}>
<Sidebar />
<Switch>
<Route path="/" component={Dashboard} />
<Route path="/archived" component={ArchivedPage} />
<Route path="/profile" component={ProfilePage} />
<Route path="/settings" component={SettingsPage} />
{/* <Redirect from="*" to="/" /> */}
</Switch>
</Router>
</div>
);
But it doesn't work. Can anyone please help me understanding if this is correct. or how can I achieve the required result.
Please let me know if you need any other details.
Thank you.
Issue
The issue is that you are exactly matching "/" to render HomePage, but then as soon as the path is any deeper, like "/archived", it no longer exactly matches and HomePage is unmounted.
You should not render a Router within another Router, you need only one router per app to provide the routing context.
Solution
Remove the inner router (and any other nested routers!!). Remove the exact prop on the "/" path and reorder the routes to specify the more specific paths before less specific paths so the Switch can actually do its job and match and render the appropriate route.
App
Reorder the more specific "/login" and "/register" paths to be matched prior to the less specific "/" path. If you had, for example, a "/login/google" path, this is more specific than "/login" and would be ordered earlier.
return (
<div>
<Router history={history}>
<Switch>
<Route path="/login" component={LoginPage} />
<Route path="/register" component={RegisterPage} />
<PrivateRoute path="/" component={HomePage} />
<Redirect to="/" />
</Switch>
</Router>
</div>
);
HomePage
Move the Dashboard to the last route position so if no other route above it is matched and returned then the dashboard is matched and rendered.
return (
<div>
<Sidebar />
<Switch>
<Route path="/archived" component={ArchivedPage} />
<Route path="/profile" component={ProfilePage} />
<Route path="/settings" component={SettingsPage} />
<Route component={Dashboard} />
</Switch>
</div>
);
in first place your doing something wrong you cant put a Router inside a Router,
you haver a Router in app then inside a component that is inside of app you have another Router thats a problem i dont know if that solves your problem but try it just delete Router in homepage
I have React Router setup in my Reactjs Project. The header Component has 4 different menu items. After login, I am getting only header component rendered but not first menu item component below it.
I have created a Homepage component which loads Header component and below that I gave Routes for different menu item pages. In the Header component for every Item, I linked it to the corresponding Item Page.
//Home Page Code.
<Router>
<Header />
<Route path='/Jobs' component={Jobs} />
<Route path='/Admin' component={Admin} />
<Route path='/Requests' component={Requests} />
</Router>
To use react router you have to wrap your routes in switch.
Switch will render the first item that matches the current route.
Because you have no switch, the routes are ignored.
To render a default site, change the path of the last route to / and it will match everything.
By setting it as last element, it will always be rendered, if no other route above matches the current route.
<Router>
<Header />
<Switch>
<Route path='/Jobs' component={Jobs} />
<Route path='/Admin' component={Admin} />
<Route path='/' component={Requests} />
</Switch>
</Router>
Hope this helps. Happy coding.
Try putting <Switch></Switch> container around your routes:
//Home Page Code.
<Router>
<Header />
<Switch>
<Route exact path='/' component={Home} />
<Route path='/Jobs' component={Jobs} />
<Route path='/Admin' component={Admin} />
<Route path='/Requests' component={Requests} />
</Switch>
</Router>
Edited: to add path for home (path='/')
Below is my attached routes, When I navigate to /login/schoolname. I get the correct component, but when I navigate to the verify, it appends onto /login/verify.
<Switch>
<Route path="/verify" component={Verify} />
<Route path="/login/:schoolName" component={Login} />
<Route path="*" component={Home} />
</Switch>
I was expecting, some thing like
localhost/verify
localhost/login/schoolname
whenever I click on the navigation
change the route in order to match the path exactly
<Route exact path="/verify" component={Verify} />
and when you manually change the route be sure to put the slash in the front of the route name
history.push("/verify");
When I try to have nested routes on my root route I run into a problem.
I have 3 "main" routes:
<Switch>
<Route path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/logout" component={Logout} />
</Switch>
On my Home component I have a nested router like this:
<div>
<Route path="/" render={() => <div>Home</div>} />
<Route path="/test" render={() => <div>Test Route</div>} />
</div>
The Home component has a sidebar HOC which contains the Links.
<Sidebar>
<Link to="/">Home</Link>
<Link to="/test">Test</Link>
<Link to="/logout">Logout</Link>
</Sidebar>
When Im on my Root component and click the Test link, the route on the nested router changes to the Test component which is correct. Whenever I go the login and/or logout route it tries to display that in the nested router in the Home component
Any idea what is going wrong?
EDIT: I've tried the example #Tholle provided. Unfortunately it still doesn't work the way I want to. See this CodeSandBox I made to reproduce my problem.
your links need to point to "/home/testX" and the nested routes need to handle "/home/testX". Also you will need a route for "/home" in the root. I don't believe the Link component is scoped to the route in which it is called. Meaning that to link to "/test1" assumes that is the base route. However, the rendering of test1 actually takes place in the home component.
To put it another way: In order to get to /home/test1 you must first get the home component (/home) to render which can then render the route for test1 (/home/test1)
Here's the codesandbox
Here is an example that provides a bit more flexibility codesandbox. This one will require a redirect of "/" because it depends on the path being used and it needs to be "/home" not "/".
Hope this helps. Hope I got it all right.
The Switch component makes sure that only the first Route that matches is rendered. To stop <Route path="/" component={Home} /> from always being rendered, you can set the exact prop to true.
Example (CodeSandbox)
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/logout" component={Logout} />
</Switch>