3

I am trying to achieve child/nested routes in Reactjs and below are the 2 methods which I found for nesting the child routes but parent routes work fine and child routes for Parent component do not.

Below are the routes how it works:

/ => Home Component
/login => Login Component
/register => Register Componet

/product/ => ProductListing Component 
/product/2 => ProductDetails Component [Expected but does not work]
/product/2/edit => ProductEdit Component [Expected but does not work]

Method 1

Below is my Main Route File:

export default function MainRouter() {
  return (
    <Router>
      <Route exact path="/" component={Home} />
      <Route exact path="/login" component={Login} />
      <Route exact path="/register" component={Register} />
      <Route exact path="/product" component={ProductRouter} />
    </Router>
  );
}

and child route for Product as shown below in ProductRouter.js file

export default function ProductRouter(props) {
  console.log(props);

  return (
    <Switch>
      <Route
        exact
        path={`${props.match.path}/:productId`}
        component={ProductDetails}
      />
      <Route
        exact
        path={`${props.match.path}/:productId/edit`}
        component={ProductEdit}
      />
      <Route exact path={`${props.match.path}`} component={ProductListing} />
    </Switch>
  );
}

Method 2

Below is my Main Route File:

export default function MainRouter() {
  return (
    <Router>
      <Route exact path="/" component={Home} />
      <Route exact path="/login" component={Login} />
      <Route exact path="/register" component={Register} />
      <Route exact path="/product/*" component={ProductRouter} />
    </Router>
  );
}

and child route for Product as shown below in ProductRouter.js file

export default function ProductRouter(props) {
  return (
    <Fragment>
      <Route exact path="/" component={ProductListing} />
      <Route
        exact
        path=":productId"
        component={ProductDetails}
      />
      <Route
        exact
        path=":productId/edit"
        component={ProductEdit}
      />
    </Fragment>
  );
}

Below are the links I checked:

Varun Sukheja
  • 6,170
  • 5
  • 51
  • 93

1 Answers1

6

exact prop on root route will exclude any sub-routes, they won't render because the root route no longer matches.

Nesting Routes

You need to remove the exact prop from the root routes (keep it on the home route so it doesn't always match)

export default function MainRouter() {
  return (
    <Router>
      <Route exact path="/" component={Home} />
      <Route path="/login" component={Login} />
      <Route path="/register" component={Register} />
      <Route path="/product" component={ProductRouter} />
    </Router>
  );
}

Use the correct path prefix (you can remove the exact prop, the Switch will only render the first match

export default function ProductRouter(props) {
  console.log(props);
  const { match: { path } } = props;

  return (
    <Switch>
      // specify more specific path before less specific path
      <Route path={`${path}/:productId/edit`} component={ProductEdit} />
      <Route path={`${path}/:productId`} component={ProductDetails} />
      <Route path={path} component={ProductListing} />
    </Switch>
  );
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • thanks @drew-reese but instead of using switch in child routes and using exact for all child routes, also works fine but in parent as you said we have to remove exact – Varun Sukheja Jun 04 '20 at 09:32