Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested routes with react router v4 / v5

I am currently struggling with nesting routes using react router v4.

The closest example was the route config in the React-Router v4 Documentation.

I want to split my app in 2 different parts.

A frontend and an admin area.

I was thinking about something like this:

<Match pattern="/" component={Frontpage}>   <Match pattern="/home" component={HomePage} />   <Match pattern="/about" component={AboutPage} /> </Match> <Match pattern="/admin" component={Backend}>   <Match pattern="/home" component={Dashboard} />   <Match pattern="/users" component={UserPage} /> </Match> <Miss component={NotFoundPage} /> 

The frontend has a different layout and style than the admin area. So within the frontpage the route home, about and so one should be the child routes.

/home should be rendered into the Frontpage component and /admin/home should be rendered within the Backend component.

I tried some variations but I always ended in not hitting /home or /admin/home.

Edit - 19.04.2017

Because this post has a lot of views right now I updated it with the final solution. I hope it helps someone.

Edit - 08.05.2017

Removed old solutions

Final solution:

This is the final solution I am using right now. This example also has a global error component like a traditional 404 page.

import React, { Component } from 'react'; import { Switch, Route, Redirect, Link } from 'react-router-dom';  const Home = () => <div><h1>Home</h1></div>; const User = () => <div><h1>User</h1></div>; const Error = () => <div><h1>Error</h1></div>  const Frontend = props => {   console.log('Frontend');   return (     <div>       <h2>Frontend</h2>       <p><Link to="/">Root</Link></p>       <p><Link to="/user">User</Link></p>       <p><Link to="/admin">Backend</Link></p>       <p><Link to="/the-route-is-swiggity-swoute">Swiggity swooty</Link></p>       <Switch>         <Route exact path='/' component={Home}/>         <Route path='/user' component={User}/>         <Redirect to={{           state: { error: true }         }} />       </Switch>       <footer>Bottom</footer>     </div>   ); }  const Backend = props => {   console.log('Backend');   return (     <div>       <h2>Backend</h2>       <p><Link to="/admin">Root</Link></p>       <p><Link to="/admin/user">User</Link></p>       <p><Link to="/">Frontend</Link></p>       <p><Link to="/admin/the-route-is-swiggity-swoute">Swiggity swooty</Link></p>       <Switch>         <Route exact path='/admin' component={Home}/>         <Route path='/admin/user' component={User}/>         <Redirect to={{           state: { error: true }         }} />       </Switch>       <footer>Bottom</footer>     </div>   ); }  class GlobalErrorSwitch extends Component {   previousLocation = this.props.location    componentWillUpdate(nextProps) {     const { location } = this.props;      if (nextProps.history.action !== 'POP'       && (!location.state || !location.state.error)) {         this.previousLocation = this.props.location     };   }    render() {     const { location } = this.props;     const isError = !!(       location.state &&       location.state.error &&       this.previousLocation !== location // not initial render     )      return (       <div>         {                     isError           ? <Route component={Error} />           : <Switch location={isError ? this.previousLocation : location}>               <Route path="/admin" component={Backend} />               <Route path="/" component={Frontend} />             </Switch>}       </div>     )   } }  class App extends Component {   render() {     return <Route component={GlobalErrorSwitch} />   } }  export default App; 
like image 919
datoml Avatar asked Jan 04 '17 22:01

datoml


People also ask

Does react router allows for nested routes?

Nested Routes are a powerful feature. While most people think React Router only routes a user from page to page, it also allows one to exchange specific fragments of the view based on the current route.

Is useHistory deprecated?

The use of history and useHistory is deprecated and should be replaced with the useNavigate hook.


1 Answers

In react-router-v4 you don't nest <Routes />. Instead, you put them inside another <Component />.


For instance

<Route path='/topics' component={Topics}>   <Route path='/topics/:topicId' component={Topic} /> </Route> 

should become

<Route path='/topics' component={Topics} /> 

with

const Topics = ({ match }) => (   <div>     <h2>Topics</h2>     <Link to={`${match.url}/exampleTopicId`}>       Example topic     </Link>     <Route path={`${match.path}/:topicId`} component={Topic}/>   </div> )  

Here is a basic example straight from the react-router documentation.

like image 143
Lyubomir Avatar answered Oct 02 '22 14:10

Lyubomir