Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Router Dom routes and sub-routes

React-router-dom / ReactJS beginner in general here.

I've got some working router code that I think can be slightly cleaned up, but attempts at doing so have failed thus far. There are certainly some gaps in my knowledge in this area. I've paged through the similar questions which has helped me expand my understanding, but I haven't successfully connected the dots at this point.

The following code seems to work fine, but I am irked by the repeated "/admin" prefix for all the admin routes.

<BrowserRouter>
    <div>
        <div className="nav-bar">
            <ul>
                <li><Link to="/admin">Home</Link></li>
                <li><Link to="/admin/content">Content</Link></li>
                ...
            </ul>
        </div>
        <div className="nav-content">
            <Route exact path="/admin" component={AdminHome}/>
            <Route path="/admin/content" component={AdminContent}/>
            ...
        </div>
    </div>
</BrowserRouter>

However, moving the "nested" routes to sub-route elements doesn't work. The JavaScript console spits out the error message "Warning: You should not use and in the same route; will be ignored."

<Route exact path="/admin" component={AdminHome}>
    <Route path="/content" component={AdminContent}/>
    ...
</Route>

Any suggestions would be greatly appreciated. I've read through a number of SO answers, and found some options in which, for example, I could use <Route path="/admin/:whatever" render={() => (...)}/>, but at this time it doesn't seem like the right path to go down.

The reason for this being, I will ultimately need route parameters further down the tree, e.g. for a URI along the lines of /admin/content/:content_type/:identifier, and ideally my AdminContent component would be agnostic about its parent route match.

Please feel free also to let me know if I'm way off base, and if there is any documentation you believe would show me the light I would love to read it.

Cheers and thanks again!

like image 461
dave Avatar asked Sep 11 '25 11:09

dave


1 Answers

Thanks to Christopher above for providing a link to some good documentation.

As per the documentation linked, the following changes are now up and running:

{/* top-level route declaration */}
<div className="nav-content">
    {/* note the removal of the exact property here */}
    <Route path="/admin" component={AdminRoutes}/>
</div>

{/* "sub-routes" (possible poor nomenclature) */}
const AdminRoutes = ({ match }) => (
    <div>
        {/* note the addition of the exact property here */}
        <Route exact path={match.url} component={AdminHome}/>
        <Route path={match.url + "/content"} component={AdminContent}/>
        <Route path={match.url + "/data-store"} component={AdminDataStore}/>
        <Route path={match.url + "/search"} component={AdminSearch}/>
        <Route path={match.url + "/communicate"} component={AdminCommunicate}/>
        <Route path={match.url + "/promote"} component={AdminPromote}/>
        <Route path={match.url + "/measure"} component={AdminMeasure}/>
        <Route path={match.url + "/experimental"} component={AdminExperimental}/>
    </div>
)

To expand a bit further: in all the examples I've seen so far using nested routes and the inbound "match" parameter, they have been implemented as above, i.e. const X = ({match}) => (...).

But it is possible, and potentially useful, to define a true React.Component subclass, in which the param match is still available via this.props.

class Content extends React.Component {

    // usage example
    render() {

        // `match` is available via inbound props
        console.log(this.props.match);

        return (
            <p>Match is {this.props.match.url}</p>
        )
    }
}

I'd like to re-iterate at this point that I am a ReactJS beginner... Please do let me know if I'm doing something stupid :)

like image 145
dave Avatar answered Sep 13 '25 04:09

dave