嵌套路由在 React Router v6 中不起作用

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

我正在尝试react router v6。根据react训练博客,我创建了路由对象并传递给

useRoutes()

function SomeOtherElement() {
  return <h1>add user</h1>;
}

const routes = [
  {
    path: 'app',
    element: <DashboardLayout />,
    children: [
      { path: 'account', element: <AccountView /> },
      {
        path: 'users', element: <UserListView />, 
        children: [
          { path: 'add', element: <SomeOtherElement /> }
        ]
      },
      { path: 'dashboard', element: <DashboardView /> },
      { path: 'products', element: <ProductListView /> },
      { path: 'settings', element: <SettingsView /> },
      { path: '*', element: <Navigate to="/404" /> }
    ]
  }];

const routing = useRoutes(routes);

但是嵌套路由不起作用。正如您在上面的对象中看到的,我想创建 URL 并为用户“add”功能呈现 UI。

浏览器中的 URL 已正确更新为 http://localhost:3000/app/users/add 但 UI 未更新。

reactjs react-router
5个回答
58
投票

React Router 的默认行为无法使用单个 Outlet 渲染多个子路由。例如 - 当需要在所有页面中都有一个 Header 并根据 Route 替换公共内容(Single Outlet)时。

这里的技巧是不为父级提供任何 element 属性,而是借助 Index 属性将此组件作为子路由提供。

如果子路由与任何子路由都不匹配,索引可以帮助我们为父路由提供默认组件。

此代码片段与 Samira 提供的代码片段类似。

<BrowserRouter>
  <Routes>
    <Route path="/" element={<App />}>
      <Route path="" element={<Home />}></Route>
      <Route path="child1"> //no element attribute here
        <Route index={true} element={<Child1 />}></Route>
        <Route path="grandChild1" element={<GrandChild1 />}></Route>
        <Route path="grandChild2" element={<GrandChild2 />}></Route>
      </Route>
    </Route>
  </Routes>
</BrowserRouter>

27
投票

正如here所解释的,您需要使用

<Outlet />
元素作为子元素的占位符,即嵌套路由。

示例:

import { Outlet } from 'react-router-dom'

// ... 

const routes = [
  {
    path: "app",
    element: (
      <>
        <DashboardLayout />
        <Outlet />
      </>
    ),
    children: [
      { path: "account", element: <AccountView /> },
      {
        path: "users",
        element: (
          <>
            <UserListView />
            <Outlet />
          </>
        ),
        children: [{ path: "add", element: <SomeOtherElement /> }],
      },
      { path: "dashboard", element: <DashboardView /> },
    ],
  },
];

或者您可能希望在父组件中包含

Outlet

export default function DashboardLayout() {
  return (
    <>
      <h1>I am Dashboard Layout</h1>
      <Outlet />
    </>
  );
}

13
投票

这对我来说是一个有用的例子,因为我想使用嵌套路由,但我不想使用 Outlet,所以我找到了它:

注意你可以用

path=":teamId"

制作动态路线
<BrowserRouter>
        <Routes>
          <Route path="/">
            <Route index={true} element={<Home />} />
          </Route>
          <Route path="/teams">
            <Route index={true} element={<ParentTeam />} />
            <Route index={false} path=":teamId" element={<Team />} />
            <Route index={false} path="new" element={<NewTeamForm />} />
          </Route>
          <Route path="*" element={<Home />} />
        </Routes>
   </BrowserRouter>

链接到codeSandBox


3
投票

对于

useRoutes
钩子,语法如下所示:

const items = [
  {
    path: "/login",
    element: <Login />,
  },
  {
    path: "/logout",
    element: <Logout />,
  },
  {
    path: "/",
    element:  <RequireAuth element={<Welcome />} />,
  },
  {
    path: "/inbox",
    element:  <RequireAuth element={<Inbox />} />
  },
  {
    path: "/dashboard",
    children: [
      {
        index: true,
        element:  <RequireAuth element={<Dashboard />} />
      },
      {
        path: "setup",
        element:  <RequireAuth element={<DashboardSetup/>} />
      },
    ]
  },


]

export default function MainContent() {
  const router = useRoutes(items);
  return router

}


0
投票

在 childns 数组中设置路径时,您应该允许在开发服务器配置中使用 api 历史记录:

    devServer: {
    historyApiFallback: true,
  }

不幸的是无法在文档中给出示例,但这里是教程

https://youtu.be/acAH2_YT6bs?list=PL6DxKON1uLOHyPVa0XhcqcW2RhDytDpAI&t=4891

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