0
votes

I have the following basic structure of nested routes/components for a react app:

  • /users -> UsersList
  • /users/:id -> UserLayout
    • /users/:id/ -> UserProfile
    • /users/:id/settings -> UserSettings
    • /users/:id/blah -> YetAnotherComponent

What I'm trying to figure out, in the context of react router v4, is how to access the :id parameter in the UserSettings component. I can access it fine in the UserLayout component, but nowhere else further downstream.

My main router definition lies in a Home component, but all the user-specific routes contain the same header information so I want all the user-specific routes to be nested. My current structure has these nested routes defined in the UserLayout component. However, no matter what I do to the layout component's route definition, I cannot get any other route than the "index" route (UserProfile) to render. When trying to access UserSettings or any other route, my top level 404 route gets hit instead.

Here's the relevant JSX (snippets of the actual components' render functions):

Home

<main>
     <Switch>
         <Route exact path="/login" component={Login} />
         <Route exact path="/users" component={UsersList} />
         <Route exact path="/users/:id" component={UserLayout} />
         <Route exact path="/" component={Home} />
         <Route component={NoMatch} />
     </Switch>
</main>

UserLayout

<div>
     <Switch>
         <Route path={`${match.url}/settings`} component={UserSettings} />
         <Route path="/users/:id/blah" component={YetAnotherComponent} />
     </Switch>
     <Route path="/users/:id" component={UserProfile} />
</div>

In the UserLayout component I've tried both path formats shown in the Switch and have tried turning on/off exact matching. The only thing I can come up with is using the Route component's render parameter to pass the id parameter, but that just seems wrong. Is that my only option?

1
why not pass it down as a prop?clodal

1 Answers

0
votes

Of course only a few minutes after I post, I figured it out. In my top-level route config, I had set the /user/:id to require an exact match. This meant that when I navigated to /user/:id/anything_else react router didn't load UserLayout at all and thus didn't get the chance to test the remainder of the routes I had configured.

So I changed this from my home component:

<Route exact path="/users/:id" component={UserLayout} />

...to this:

<Route path="/users/:id" component={UserLayout} />

... and now all is well with the world.