【问题标题】:React Router nested routing in the base urlReact Router 在基本 url 中嵌套路由
【发布时间】:2020-04-13 15:54:46
【问题描述】:

我修改了docs 中的 React Router 嵌套路由中给出的示例,以在基本 url 中设置嵌套路由,例如 this

我想要像 /Home1/Home2 这样的嵌套路由直接在根 url 下。

export default function NestingExample() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/topics">Topics</Link>
          </li>
        </ul>
        <hr />
        <Switch>
          <Route exact path="/">
            <Home />
          </Route>
          <Route path="/topics">
            <Topics />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

function Home() {
  let { path, url } = useRouteMatch();
  console.log({url, path});

  return (
    <div>
      <h2>Homes</h2>
      <ul>
        <li>
          <Link to="/home1">Home 1</Link> 
          {/* also tried   <Link to={`${url}/home1`}>Home 1</Link> */}
        </li>
        <li>
        <Link to="/home2">Home 2</Link>
        </li>
      </ul>

      <Switch>
        <Route exact path={path}>
          <h3>Please select a home.</h3>
        </Route>
        <Route path={`${path}/home1`}>
          <Home1 />
        </Route>
        <Route path={`${path}/home2`}>
          <Home2 />
        </Route>
      </Switch>
    </div>
  );
}

function Home1() {
  return (
    <div>
      <h3>Home1 Content</h3>
    </div>
  );
}

function Home2() {
  return (
    <div>
      <h3>Home2 Content</h3>
    </div>
  );
}

浏览器中未显示错误,但未显示 Home1 页面。 不可以直接在root下设置嵌套路由吗?

【问题讨论】:

    标签: reactjs react-router react-router-dom


    【解决方案1】:

    你需要重新排序你的路由,所以基础路由是堆栈中的最后一个路由(使用 strict 关键字)

    例如。

    
    <Switch>
        <Route strict path="/users" component={UsersRoutes} />
        <Route strict path="/" compoent={PublicRoutes} />
    </Switch>
    

    这样,每个页面都可以呈现自己的Not Found 页面。

    例如。

    // within PublicRoutes
    <Switch>
        <Route exact path={path} component={() => <h1>Public Page</h1>} />
        <Route path="*" component={() => <h1>Not found</h1>} />
    </Switch>
    

    https://codesandbox.io/s/react-router-nesting-025cn?file=/example.js

    【讨论】:

    • 你能否通过 fork mine 在代码和框中显示一个运行示例?
    • @SuleymanSah 给你。我更新了回复。您可以对此进行投票以帮助其他人。
    【解决方案2】:

    我没有尝试过,但我的猜测是通过在顶级路由器的路由中使用“exact”关键字,嵌套结构不再匹配 url。如果您删除该属性,它会起作用吗?

    更多信息:https://reacttraining.com/react-router/web/api/Route/exact-bool

    【讨论】:

    • 删除那里的确切地址会导致所有 url 转到基本主路由。
    • 将该路线移动到路线的底部 :)
    • 我试过了,但结果一样。如果你有电脑,你可以玩我的游乐场。
    【解决方案3】:

    我最终创建了一个单独的/home 路由,并将/ 重定向到/home 以便能够在家中使用嵌套路由。

    但我仍然对更聪明的答案感兴趣。

    export default function NestingExample() {
      return (
        <Router>
          <div>
            <ul>
              <li>
                <Link to="/">Home</Link>
              </li>
              <li>
                <Link to="/topics">Topics</Link>
              </li>
            </ul>
            <hr />
            <Switch>
              <Route exact path="/">
                <Redirect to="/home" />
              </Route>
              <Route path="/home">
                <Home />
              </Route>
              <Route path="/topics">
                <Topics />
              </Route>
            </Switch>
          </div>
        </Router>
      );
    }
    
    function Home() {
      let { path, url } = useRouteMatch();
    
      return (
        <div>
          <h2>Homes</h2>
          <ul>
            <li>
              <Link to={`${url}/home1`}>Home 1</Link>
            </li>
            <li>
              <Link to={`${url}/home2`}>Home 2</Link>
            </li>
          </ul>
    
          <Switch>
            <Route exact path={path}>
              <h3>Please select a home.</h3>
            </Route>
            <Route path={`${path}/home1`}>
              <Home1 />
            </Route>
            <Route path={`${path}/home2`}>
              <Home2 />
            </Route>
          </Switch>
        </div>
      );
    }
    
    function Home1() {
      return (
        <div>
          <h3>Home1 Content</h3>
        </div>
      );
    }
    
    function Home2() {
      return (
        <div>
          <h3>Home2 Content</h3>
        </div>
      );
    }
    

    【讨论】:

      【解决方案4】:

      问题是 react-router 不会为您去除 pathurl 的尾部斜杠。

      所以在根路径:path === '/'

      所以当你连接它时:

       <Route exact path={`${path}/home1`}>
      

      你最终得到

       <Route exact path="//home">
      

      与任何路线都不匹配

      解决这个问题的最简单方法是通过删除尾部斜杠来规范化路径和 url 变量

      let { path, url } = useRouteMatch();
      //strip trailing slashes
      path = path.replace(/\/$/, '');
      url = url.replace(/\/$/, '');
      

      你的完整例子是

      export default function NestingExample() {
        return (
          <Router>
            <div>
              <ul>
                <li>
                  <Link to="/">Home</Link>
                </li>
                <li>
                  <Link to="/topics">Topics</Link>
                </li>
              </ul>
              <hr />
              <Switch>
                <Route path="/">
                  <Home />
                </Route>
                {/** Note That both "/" and "/home" will work */}
                <Route path="/home">
                  <Home />
                </Route>
                <Route path="/topics">
                  <Topics />
                </Route>
              </Switch>
            </div>
          </Router>
        );
      }
      
      function Home() {
        let { path, url } = useRouteMatch();
        //strip trailing slashes
        path = path.replace(/\/$/, '');
        url = url.replace(/\/$/, '');
      
        return (
          <div>
            <h2>Homes</h2>
            <ul>
              <li>
                <Link to={`${url}/home1`}>Home 1</Link>
              </li>
              <li>
                <Link to={`${url}/home2`}>Home 2</Link>
              </li>
            </ul>
      
            <Switch>
              <Route exact path={${path}/}>
                <h3>Please select a home.</h3>
              </Route>
              <Route exact path={`${path}/home1`}>
                <Home1 />
              </Route>
              <Route exact path={`${path}/home2`}>
                <Home2 />
              </Route>
            </Switch>
          </div>
        );
      }
      
      function Home1() {
        return (
          <div>
            <h3>Home1 Content</h3>
          </div>
        );
      }
      
      function Home2() {
        return (
          <div>
            <h3>Home2 Content</h3>
          </div>
        );
      }
      

      【讨论】:

      • 我用您的解决方案创建了sandbox。主页有效,但主题无效。
      • 这不像@SuleymanSah 提到的那样工作。我在下面发布了一个。
      猜你喜欢
      • 2016-03-06
      • 1970-01-01
      • 2017-11-11
      • 1970-01-01
      • 2015-02-21
      • 2019-11-04
      • 1970-01-01
      • 2021-12-30
      相关资源
      最近更新 更多