React router master detail setup using nested syntax - javascript

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>});}

Related

Cant use page routing

So I'm working an a project where the user should click the link and than should go on the login or create account page. I'm using routing for that but as soon as I put Routes to use route and add the navigation link there my webpage turns blank:
That was the code and this is the page at the moment:
No error shown no nothing! help pls!
First I used Switch than the webpage didn't allow me to use it, so I changed to Routes
Instead of
<Routes>
<Route path="login" exact>
<Login />
</Route>
<Route path="create" exact>
<Signup />
</Route>
</Routes>
It should be like
<Routes>
<Route exact path="login" element={<Login />} />
<Route path="/create" element={<Signup />} />
</Routes>
Here is a link to code sandbox
Here is how to render pages without navbar
So i wrote it wrong instead it should be written like this:
<Routes>
<Route exact path="login" element={<Login />} />
<Route path="/create" element={<Signup />} />
</Routes>
But everything else that is outside the Routes will be render in the other page too, this is very useful for navbar!

React Router v6 index routes giving trailing slash error

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

How do i add an error page to my react router code?

so this is my code
<Router>
<Route path="/" component={Nav}/>
<Route path="/" exact component={Home}/>
<Route path="/updates" exact component={Updates} />
<Route path="/author" exact component={Author} />
<Route path="/" component={Footer}/>
</Router>
It works completely fine i just have a slight problem with it. If i were to go to lets say Author page i can just type /author and it will show not only the author but the navbar and footer because i didn't make them exact on purpose but the problem is if i were to make a random link such as ./ejfjife it will still show the navbar and footer i want to make it so if the user made up a link that doesn't exist it'll redirect them to some kind of 'this page doesn't exist' error
thank you
If you always want your Nav and Footer to be present, they shouldn't even be listed under a Route. They can exist outside your Router. Then your Home component can take a path="/" exact and any other route can take the path="/" Component={Error404}. Like this:
<App>
<Nav />
<Router>
<Route path="/" exact component={Home}/>
<Route path="/updates" exact component={Updates} />
<Route path="/author" exact component={Author} />
<Route path="/" component={Error404}/>
</Router>
<Footer />
</App>

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

How to move between nested components with React Router

I have been working along just fine with react router until I had to try and nest components and get my nav bar to show the path. For example I want to go from my matches page to a portfolio page, then I want the url to reflect this(....../#/matches/portfolio).
To me the docs seem to explain how to do this however I can only get the url to change and not the page content. No error is show just noting happens to the view.
Here is my router containing nested routes:
ReactDOM.render(
<Router history={hashHistory}>
<Route path="/" component={App}>
<Route path="login" component={Login} />
<Route path="home" component={Home} />
<Route path="matches" component={Matches}>
<Route path="portfolio" component={Portfolio}>
<Route path="search" component={Search} />
</Route>
</Route>
<Route path="create" component={Create} />
<Route path="join" component={Join}/>
</Route>
</Router>
, document.getElementById('app'));
And if I am on the matches page and want to link to a portfolio I have a button with:
<Link to="matches/portfolio">To Portfolio</Link>
(Ideally I would like to have it have a portfolioId attached to the url but I am trying to keep it simple at the moment)
The repo can be found here:
https://github.com/muddybarefeet/pirateStocks and then main router is in server/client/src/app.jsx and all components in server/client/src/components.
To see the project run nodemon server.js and webpack
The following is how I got my routes to work. This is not what the docs say but it works!
ReactDOM.render(
<Router history={hashHistory}>
<Route path="/" component={App}>
<Route path="/login" component={Login} />
<Route path="/home" component={Home} />
<Route path="/join" component={Join}/>
<Route path="/matches" component={Matches} />
<Route path="/matches/portfolio" component={Portfolio} />
<Route path="/matches/portfolio/search" component={Search} />
<Route path="create" component={Create} />
</Route>
</Router>
, document.getElementById('app'));
And then route with the following:
<Link to="/matches/portfolio">To Portfolio</Link>

Categories

Resources