React Router v6 嵌套惰性与 useRoutes 挂钩问题

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

使用

react-router v6
react v18
。我不确定我错过了什么,但似乎带有惰性的嵌套组件不起作用。 我有这个文件结构:

  • routes/root.tsx
  • routes/profiles/Profiles.tsx
  • routes/profiles/ProfileDetail.tsx
  • routes/profiles/ProfilesList.tsx

现在在根目录中,我有一个定义如下的路由器:

createBrowserRouter([
  {
    path: "/",
    element: <AuthLayout />,
    children: [
      {
        path: "/profiles/*",
        lazy: () => import("./profiles/Profiles.tsx"),
      },
    ],
  },
])

然后在

Prfiles.tsx

export const Component = () => {
  // some code

  return useRoutes([
    {
      path: "/",
      lazy: () => import("./ProfilesList"),
    },
    {
      path: "/:id",
      lazy: () => import("./ProfileDetail"),
    },
  ])
}

ProfilesList.tsx
ProfileDetail.tsx
都会导出
Component

AuthLayout
被渲染,但是当我转到
/profiles
/profiles/someId
时,它不会渲染任何东西。它只显示空白页面。 (带有包含在
AuthLayout
中的菜单。
Profiles.tsx
中的组件确实会渲染,但配置文件列表和详细信息不会渲染。

我错过了什么吗?我不明白为什么这不起作用。

我尝试不延迟加载根路由器配置中的

Profiles.tsx
组件。如果我不使用惰性,而是使用
Profiles.tsx
组件内的元素作为路由。它按预期工作,但是当我使用惰性选项时它不起作用。

由于惰性函数只是获取文件的函数并使用其组件、加载器等...我怀疑它的工作方式与其他路线相同,例如

Profile.tsx
本身,其中导出
Component
并且比
lazy
中的
createBrowserRouter
确实有效。

reactjs react-hooks react-router react-router-dom
1个回答
0
投票

我认为,当涉及到使用 Route 组件的

lazy
属性延迟加载组件时,当包含以下注释时,
官方文档
可能会有点误导:

此功能仅在使用数据路由器时才有效,请参阅选择路由器

似乎需要注意的是,

lazy
仅在
createBrowserRouter
声明中字面使用时才有效。由于
"/profiles"
路由渲染后代路由,因此数据路由器很难(或不可能)知道哪些路由将被渲染并且在运行时可用,因此
Profiles
组件无法使用 React- Router的延迟加载解决方案。

您需要在创建路由器的位置执行所有路由/加载。

Profiles
组件应转换为布局路线组件,例如它为嵌套路由渲染
Outlet
,而不是直接手动渲染后代路由。

示例:

配置文件.tsx

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

export const Component = () => {
  // some code

  return (
    ...
    <Outlet />
    ...
  );
}
const router = createBrowserRouter([
  {
    path: "/",
    element: <AuthLayout />,
    children: [
      {
        path: "/profiles",
        lazy: () => import("./profiles/Profiles.tsx"),
        children: [
          {
            index: true,
            lazy: () => import("./profiles/ProfilesList.tsx"),
          },
          {
            path: ":id",
            lazy: () => import("./profiles/ProfileDetail.tsx"),
          },
        ],
      },
    ],
  },
]);

或者,如果您仍然想进行代码分割并使用后代路由,则可以使用常规的 React 延迟导入解决方案。

示例:

ProfilesList
ProfileDetail
都应该默认导出

const Component = () => {
  ...
};

export default Component;

配置文件.tsx

import { lazy, Suspense } from "react";
import { useRoutes } from "react-router-dom";

const ProfilesList = lazy(() => import("./ProfilesList"));
const ProfileDetail = lazy(() => import("./ProfileDetail"));

export const Component = () => {
  // some code

  const profilesRoutes = useRoutes([
    {
      path: "/",
      element: <ProfilesList />,
    },
    {
      path: "/:id",
      element: <ProfileDetail />,
    },
  ]);

  return (
    <>
      <h1>Profiles</h1>
      <Suspense fallback={<h1>Loading...</h1>}>{profilesRoutes}</Suspense>
    </>
  );
};
© www.soinside.com 2019 - 2024. All rights reserved.