CalgaryFlames
CalgaryFlames

Reputation: 706

Unable to reach out to grandchild router component with nested React-Router-Dom v5

I have implemented a nested react-router application. With the outline for routing structure below, it works fine to route 1,2,3 with (1). Also, when I land on 3, it displays sidebar and component (1) properly. When I click the Link in the component (1) to link to (2), it doesn't work. I was looking for similar questions but didn't find the answer. Can you let me know what I missed here?

// Outline for routing structure
App.js
L 1
L 2
L 3
  L sidebar // link to (1), (2). This should be docked when rendering (1), (2)
  L (1) // path:'/dashboard' Default & Link to (2)
  L (2) // path:'/dashboard/detail'

import "./App.css";
import React from "react";

import { Switch, BrowserRouter, Route, withRouter } from "react-router-dom";

function App({ location }) {
   return (
    <div>
      <Switch>
        <Route exact path="/1" render={() => <1/>} />
        <Route exact path="/2" render={() => <2/>} />
        <Route exact path="/dashboard" render={() => <3/>} />      
      </Switch>    
    </div>
  );
}

export default App;

import React from "react";
import (1) from "./(1)";
import Sidebar from "./Sidebar ";
import { Switch, Route } from "react-router-dom";
import (2)from "./(2)";
import { Container, Row, Col } from "react-bootstrap";

const 3= () => {
  return (
  <div>
     <Route path="/dashboard">
      <Row>
        <Col lg={5}>
          <Sidebar />
        </Col>
        <Col lg={7}>

            <Switch>
              <Route
                path="/dashboard"
                render={() => <(1)/>}
                exact
              />
              <Route
                path="/dashboard/detail"
                render={() => <(2)/>}
                exact
              />            
            </Switch> 
        </Col>
      </Row>
    </Route>
  </div>

  );
};

export default 3;
import React from "react";
import { Link } from "react-router-dom";

const (2)= () => {
  return (
    <>     
      <div>
      <Link to="/dashboard/detail">Go to Detail</Link>
      </div>
    </>
  );
};

export default (2);

Upvotes: 1

Views: 220

Answers (1)

Drew Reese
Drew Reese

Reputation: 203587

Issue

Your root "/dashboard" path that is being exactly matched precludes any other nested sub-routes from matching and being rendered. In other words "/dashboard/detail" no longer exactly matches the root "/dashboard" path specified.

Solution

Remove the exact prop on the root dashboard route so any route with a "/dashboard" path prefix can be matched and rendered by the nested Switch component.

Tip: when using the Switch component, order your more specific paths before less specific paths and you won't need to specify the exact prop across the board. Within a Switch path order and specificity matter.

App

function App({ location }) {
  return (
    <div>
      <Switch>
        <Route exact path="/1" render={() => <1/>} />
        <Route exact path="/2" render={() => <2/>} />
        <Route path="/dashboard" render={() => <3/>} />      
      </Switch>    
    </div>
  );
}

Component 3

const 3= () => {
  return (
    <div>
      <Route path="/dashboard">
        <Row>
          <Col lg={5}>
            <Sidebar />
          </Col>
          <Col lg={7}>
            <Switch>
              <Route
                path="/dashboard/detail"
                render={() => <(2)/>}
              />
              <Route
                path="/dashboard"
                render={() => <(1)/>}
              />   
            </Switch> 
          </Col>
        </Row>
      </Route>
    </div>
  );
};

Upvotes: 1

Related Questions