如何使用 React Router v6 创建子路由器?

问题描述 投票:0回答:2

这是我当前的 React Router 实现:

const router = createBrowserRouter([
    {
      path: "/",
      element: (
        <Page activeNav="home" >
          <Home />
        </Page>
      )
    },
    {
      path: "/about",
      element: (
        <Page activeNav="about" >
          <About />
        </Page>
      )
    },
    {
      path: "/blog",
      element: (
        <Page activeNav="blog">
          <Blog />
        </Page>
      )
    },
    {
      path: "/blog/:postName",
      element: (
        <Page activeNav="blog" >
          <Post />
        </Page>
      ),
      loader: ({ params }) => params.postName
    },
    {
      path: "/chess",
      element: <ChessRouter />
    }
  ])

最后一条路线,

/chess
很重要。我正在寻找定义路线,例如
/chess/play
/chess/login
/chess/register
等。我最初的想法是仅将另一个
Router
作为
/chess
路径的元素,然后所有这些路径都将被路由从那里。但是,这会引发错误:

You cannot render a <Router> inside another <Router>. You should never have more than one in your app.

我还尝试在

/chess
路线上使用children属性,但是当我转到
/chess/play
等时,这不会呈现任何内容。

实现子路径的正确方法是什么(不确定正确的词)?

javascript reactjs typescript react-router react-router-dom
2个回答
13
投票

您不能在另一个路由器组件中渲染一个路由器组件,这是正确的,因为这是一个不变的违规。每个 React 应用程序只需要一个路由器和路由上下文。

要在

"/chess"
上渲染子路线,有两个选项:

  1. 在路由配置声明中渲染嵌套路由。此 需要

    ChessRouter
    组件来渲染
    Outlet
    组件,以便嵌套路由将其
    element
    内容渲染到其中。嵌套路由将能够使用新的 RRDv6.4 数据 API。

    const router = createBrowserRouter([
      ...,
      {
        path: "/chess",
        element: <ChessRouter />,
        children: [
          ...,
          {
            path: "play",
            element: <ChessPlay />
          },
          ... other chess sub-rotues
        ],
      }
    ]);
    
    const ChessRouter = () => {
      ...
    
      return (
        ...
        <Outlet />
        ...
      );
    };
    
  2. 渲染带有尾随通配符 (

    "*"
    ) 字符的根路由,该字符也允许匹配后代路由。这允许
    ChessRouter
    组件渲染后代路由,即带有一组
    Routes
    组件的
    Route
    组件。下降路线将无法能够使用 RRDv6.4 数据 API。

    const router = createBrowserRouter([
      ...,
      {
        path: "/chess/*",
        element: <ChessRouter />,
      }
    ]);
    
    const ChessRouter = () => {
      ...
    
      return (
        ...
        <Routes>
          ...
          <Route path="/play" element={<ChessPlay />} />
          ... other chess sub-rotues
        </Routes>
        ...
      );
    };
    

6
投票

如果您的 ChessRouter 除了路由声明之外不包含任何附加功能,您可以完全删除它并使用索引路由。

利用德鲁所拥有的:

const router = createBrowserRouter([
  ...,
  {
    path: "/chess",
    children: [{
        index: true,
        element: <ChessPlay />    // The default component to load at '/chess'
      },
      {
        path: "play",
        element: <ChessPlay />
      },
      ... other chess sub-routes
    ],
  }
]);

这将使 /chess 下的所有子路由正常工作,并防止用户点击基本 /chess 路由时显示空白页面。

© www.soinside.com 2019 - 2024. All rights reserved.