Nested routes with react router v4 / v5

后端 未结 11 1880
广开言路
广开言路 2020-11-22 12:34

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 t

相关标签:
11条回答
  • 2020-11-22 13:26

    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.

    0 讨论(0)
  • 2020-11-22 13:28

    I succeeded in defining nested routes by wrapping with Switch and define nested route before than root route.

    <BrowserRouter>
      <Switch>
        <Route path="/staffs/:id/edit" component={StaffEdit} />
        <Route path="/staffs/:id" component={StaffShow} />
        <Route path="/staffs" component={StaffIndex} />
      </Switch>
    </BrowserRouter>
    

    Reference: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Switch.md

    0 讨论(0)
  • 2020-11-22 13:28

    Using Hooks

    The latest update with hooks is to use useRouteMatch.

    Main routing component

    
    export default function NestingExample() {
      return (
        <Router>
          <Switch>
           <Route path="/topics">
             <Topics />
           </Route>
         </Switch>
        </Router>
      );
    }
    

    Child component

    function Topics() {
      // The `path` lets us build <Route> paths 
      // while the `url` lets us build relative links.
    
      let { path, url } = useRouteMatch();
    
      return (
        <div>
          <h2>Topics</h2>
          <h5>
            <Link to={`${url}/otherpath`}>/topics/otherpath/</Link>
          </h5>
          <ul>
            <li>
              <Link to={`${url}/topic1`}>/topics/topic1/</Link>
            </li>
            <li>
              <Link to={`${url}/topic2`}>/topics/topic2</Link>
            </li>
          </ul>
    
          // You can then use nested routing inside the child itself
          <Switch>
            <Route exact path={path}>
              <h3>Please select a topic.</h3>
            </Route>
            <Route path={`${path}/:topicId`}>
              <Topic />
            </Route>
            <Route path={`${path}/otherpath`>
              <OtherPath/>
            </Route>
          </Switch>
        </div>
      );
    }
    
    
    0 讨论(0)
  • 2020-11-22 13:30

    A complete answer for React Router v6 or version 6 just in case needed.

    import Dashboard from "./dashboard/Dashboard";
    import DashboardDefaultContent from "./dashboard/dashboard-default-content";
    import { Route, Routes } from "react-router";
    import { useRoutes } from "react-router-dom";
    
    /*Routes is used to be Switch*/
    const Router = () => {
    
      return (
        <Routes>
          <Route path="/" element={<LandingPage />} />
          <Route path="games" element={<Games />} />
          <Route path="game-details/:id" element={<GameDetails />} />
          <Route path="dashboard" element={<Dashboard />}>
            <Route path="/" element={<DashboardDefaultContent />} />
            <Route path="inbox" element={<Inbox />} />
            <Route path="settings-and-privacy" element={<SettingsAndPrivacy />} />
            <Route path="*" element={<NotFound />} />
          </Route>
          <Route path="*" element={<NotFound />} />
        </Routes>
      );
    };
    export default Router;
    
    import DashboardSidebarNavigation from "./dashboard-sidebar-navigation";
    import { Grid } from "@material-ui/core";
    import { Outlet } from "react-router";
    
    const Dashboard = () => {
      return (
        <Grid
          container
          direction="row"
          justify="flex-start"
          alignItems="flex-start"
        >
          <DashboardSidebarNavigation />
          <Outlet />
        </Grid>
      );
    };
    
    export default Dashboard;
    

    Github repo is here. https://github.com/webmasterdevlin/react-router-6-demo

    0 讨论(0)
  • 2020-11-22 13:34

    React Router v6

    allows to use both nested routes (like in v3) and separate, splitted routes (v4, v5).

    Nested Routes

    Keep all routes in one place for small/medium size apps:

    <Routes>
      <Route path="/" element={<Home />} >
        <Route path="user" element={<User />} /> 
        <Route path="dash" element={<Dashboard />} /> 
      </Route>
    </Routes>
    

    const App = () => {
      return (
        <BrowserRouter>
          <Routes>
            // /js is start path of stack snippet
            <Route path="/js" element={<Home />} >
              <Route path="user" element={<User />} />
              <Route path="dash" element={<Dashboard />} />
            </Route>
          </Routes>
        </BrowserRouter>
      );
    }
    
    const Home = () => {
      const location = useLocation()
      return (
        <div>
          <p>URL path: {location.pathname}</p>
          <Outlet />
          <p>
            <Link to="user" style={{paddingRight: "10px"}}>user</Link>
            <Link to="dash">dashboard</Link>
          </p>
        </div>
      )
    }
    
    const User = () => <div>User profile</div>
    const Dashboard = () => <div>Dashboard</div>
    
    ReactDOM.render(<App />, document.getElementById("root"));
    <div id="root"></div>
        <script src="https://unpkg.com/react@16.13.1/umd/react.production.min.js"></script>
        <script src="https://unpkg.com/react-dom@16.13.1/umd/react-dom.production.min.js"></script>
        <script src="https://unpkg.com/history@5.0.0/umd/history.production.min.js"></script>
        <script src="https://unpkg.com/react-router@6.0.0-alpha.5/umd/react-router.production.min.js"></script>
        <script src="https://unpkg.com/react-router-dom@6.0.0-alpha.5/umd/react-router-dom.production.min.js"></script>
        <script>var { BrowserRouter, Routes, Route, Link, Outlet, useNavigate, useLocation } = window.ReactRouterDOM;</script>

    Alternative: Define your routes as plain JavaScript objects via useRoutes.

    Separate Routes

    You can use separates routes to meet requirements of larger apps like code splitting:

    // inside App.jsx:
    <Routes>
      <Route path="/*" element={<Home />} />
    </Routes>
    
    // inside Home.jsx:
    <Routes>
      <Route path="user" element={<User />} />
      <Route path="dash" element={<Dashboard />} />
    </Routes>
    

    const App = () => {
      return (
        <BrowserRouter>
          <Routes>
            // /js is start path of stack snippet
            <Route path="/js/*" element={<Home />} />
          </Routes>
        </BrowserRouter>
      );
    }
    
    const Home = () => {
      const location = useLocation()
      return (
        <div>
          <p>URL path: {location.pathname}</p>
          <Routes>
            <Route path="user" element={<User />} />
            <Route path="dash" element={<Dashboard />} />
          </Routes>
          <p>
            <Link to="user" style={{paddingRight: "5px"}}>user</Link>
            <Link to="dash">dashboard</Link>
          </p>
        </div>
      )
    }
    
    const User = () => <div>User profile</div>
    const Dashboard = () => <div>Dashboard</div>
    
    ReactDOM.render(<App />, document.getElementById("root"));
    <div id="root"></div>
        <script src="https://unpkg.com/react@16.13.1/umd/react.production.min.js"></script>
        <script src="https://unpkg.com/react-dom@16.13.1/umd/react-dom.production.min.js"></script>
        <script src="https://unpkg.com/history@5.0.0/umd/history.production.min.js"></script>
        <script src="https://unpkg.com/react-router@6.0.0-alpha.5/umd/react-router.production.min.js"></script>
        <script src="https://unpkg.com/react-router-dom@6.0.0-alpha.5/umd/react-router-dom.production.min.js"></script>
        <script>var { BrowserRouter, Routes, Route, Link, Outlet, useNavigate, useLocation } = window.ReactRouterDOM;</script>

    0 讨论(0)
提交回复
热议问题