React Router v6 index routes giving trailing slash error - javascript

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

Related

Different Nav based on route react router

Hello all I did use search but I couldnt find anything that solved this problem.
I need two navbars one for most pages and one for a specific set of routes
code
<BrowserRouter>
<Header />
<Switch>
<Route exact path="/" component={() => <div>home</div>} />
<Route exact path="/services" component={() => <div>services</div>} />
</Switch>
</BrowserRouter>
I need something that would say render all routes except /services/* because /services/* has different
I thought about changing things inside Header but there will be too many changes it would be easier to have different component.
You could set up a condition inside your path. I haven't tested this, but something in that nature could help you combine and separate certain routes.
<BrowserRouter>
<Header />
<Switch>
<Route exact path={"/allComponents" || "/"} component={() => <div>home</div>} />
<Route exact path="/services" component={() => <div>services</div>} />
</Switch>
</BrowserRouter>

react router v4 route changed but did not render the correct component

I have 2 level of route, the first layer it look like this
<BrowserRouter>
<div>
<AuthRoute></AuthRoute>
<Switch>
<Route path='/dashboard' component={Dashboard} />
</Switch>
</div>
</BrowserRouter>
where in AuthRoute I have a redirect upon componentDidMount
this.props.history.replace(/dashboard/redirected)
The problem is within the dashboard/index which is my 2nd level of route config
<BrowserRouter>
<Switch>
<Route exact path='/dashboard' component={()=><h1>dashboard index</h1>} />
<Route exact path='/dashboard/somewhere' component={()=><h1>somewhere</h1>} />
<Route exact path='/dashboard/redirected' component={() => <h1>redirected</h1>} />
</Switch>
</BrowserRouter>
The route changed to /dashboard/redirect but the component didn't render the correct one if you refresh on says /dashboard/somewhere or /dashboard/
You can see the problem clearer in the demo I setup https://codesandbox.io/s/v0v4qok38l
You only need one <BrowserRouter> in the application - removing it from dashboard/index.js will fix your issue.

React router master detail setup using nested syntax

I'm writing an app that has a master / detail type setup.
I want two different routes:
/items Item listing page (all items)
/items/item-slug Item detail page (single item)
I have the following config:
<Route name="app" component={App} path="/">
<IndexRoute component={ItemList} />
<Route name="itemList" component={ItemList} path="items">
<Route name="itemDetail" component={ItemDetail} path=":itemSlug" />
</Route>
</Route>
The listing route works but the item route is never reached (shows listing page instead of item page).
Everything works as expected with the following structure:
<Route name="app" component={App} path="/">
<IndexRoute component={ItemList} />
<Route name="itemList" component={ItemList} path="items" />
<Route name="itemDetail" component={ItemDetail} path="items/:itemSlug" />
</Route>
... but after reading react-router's documentation I was under the impression that I could use nesting to my favour.
Are there any modifications I can make to the first snippet so that the routing works as expected, or is the second snippet the correct way to address this functionality?
Assuming that you don't want to nest ItemDetail inside ItemList, you can't nest one inside the other. What I would do is something like this:
<Route name="app" component={App} path="/">
<IndexRedirect to="items" />
<Route path="items">
<IndexRoute name="itemList" component={ItemList} />
<Route name="itemDetail" component={ItemDetail} path=":itemSlug" />
</Route>
</Route>
Try
<Route name="app" component={App} path="/">
<IndexRoute component={ItemList} />
<Route name="itemList" component={ItemList} path="items">
<Route name="itemDetail" component={ItemDetail} path=":itemSlug" />
</Route>
</Route>
Stripping the items/ path component from the itemDetail route
As you are nesting routes the parent component needs to have the children rendered.
So in ItemList component you need to add to the render function {this.props.children} to render out ItemDetail
so
render(){return(<div>{this.props.children}</div>});}

react-router - sub-routes not showing

Im trying to implement react-router and something is missing. I cannot browse to
domain.com/projects/-KBnGTGY0WZQSZIa7nRc
Which i expect to be a sub-domain of projects with a projectId
This is my routes setup
<Router history={new HashHistory}>
<Route path="/" component={Main}>
<Route path="profile" component={Profile} onEnter={requireAuth} />
<Route path="projects" component={Projects} >
<Route path="/projects/:projectId" component={ProjectsDetails} />
</Route >
<Route path="login" component={Login} />
<Route path="logout" component={Logout} />
<Route path="register" component={Register} />
<Route path="*" component={Register}/>
</Route>
</Router>
I also Link to the sub-route like this
<Link to={`/projects/${this.props.item.key}`}>
<h3 className="project-list-h3">{this.state.text} </h3>
</Link>
Its simply reverting to the * which is the registration page.
Is there something i need to add to the {ProjectsDetails} page? It dosnt even call it so i believe the problem is somewhere else.
Thanks
In the example you have provided above your route would be /projects/projects/:id. If you wish to a route like path="/projects/:projectId" you would not nest it inside the project route. I have included a link to the offical doc that gives an overview of this concept. Official docs routes.
If you have a look at the example it shows a similar nested route to yours, note that you combine the path of the parent and child to get the path of the child route.
<Router>
<Route path="/" component={App}>
<Route path="about" component={About} />
<Route path="inbox" component={Inbox}>
<Route path="messages/:id" component={Message} />
</Route>
</Route>
/inbox/messages/:id App -> Inbox -> Message

Nesting in Default Route

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>

Categories

Resources