我有一个页面布局与3个独立的部分:侧栏,标题和正文.我希望从子路由填充主体,而父路由定义头部或侧边栏-但在try 使用提供者和上下文方法后,我找不到正确的方法.

以下是我想要实现的基线/伪代码:

示例布局:

Layout.tsx

export function DefaultLayout() {
  return (
    <div className="sidebar">
      <!-- sidebar content goes here -->
    </div>
    <div className="page">
      <div className="page-header">
        <!-- header content goes here -->
      </div>
      <div className="page-body">
        <Outlet />
      </div>
    </div>
  );
}

路由示例:

路由

import { Route } from "react-路由-dom";

<Route element={<DefaultLayout />}>
  <Route
    path="/dashboard"
    sidebar={<DefaultSidebar />}
    header={<DashboardHeader />}
  >
    <Route path="home" element={<DashboardHomePage />}>
    <Route path="stats" element={<DashboardStatsPage />}>
    <Route path="help" element={<DashboardHelpPage />}>
  </Route>
  <Route path="/user" sidebar={<UserSidebar />} header={<UserHeader />}>
    <Route path="overview" element={<UserOverviewPage />}>
    <Route path="accounts" element={<UserAccountsPage />}>
  </Route>
</Route>

如上面的简化示例所示,我希望在父路由中定义总体布局,同时在嵌套路由中"填充"布局区段.sidebar={}header={}只是本例的伪代码,我意识到它可能是另一个element={}包装器的一部分.

我try 过通过创建一个<SidebarProvider><HeaderProvider>组件来解决这个问题,使用类似useOutletContext的组件并向下传递状态,但这似乎不起作用,而且很快变得非常复杂(无限循环,等等).

那么,从头开始:有什么方法可以实现上述行为?如果是通过Provider ,我应该如何组织它们?

Edit:为了澄清混淆:我想要将布局、侧边栏、标题和路由(包含正文)分离.我认为这对于提供者来说应该是可能的,因为我发现了在类似情况下使用提供者的例子,只是为了设置一个页面标题,当我试图用多个元素来扩展它们时,这些标题似乎不起作用.包含侧边栏和页眉的提供者示例会是什么样子?

本质上:我想从子路由向父路由传递2个元素.我该怎么做?

推荐答案

我建议将headersidebar作为props 添加到DefaultLayout路由组件中,并相应地呈现它们.不要忘记,在Reaction中,我们使用classNameprops 而不是classprops .

const DefaultLayout = ({ header, sidebar }) => (
  <div className="layout">
    <div className="sidebar">{sidebar}</div>
    <div className="page">
      <div className="page-header">{header}</div>
      <div className="page-body">
        <Outlet />
      </div>
    </div>
  </div>
);

请注意,我向整个元素的整体周围元素添加了一个"layout"类,以便使用网格布局和分配的区域来设置整体页面布局.

示例css:

.layout {
  display: grid;
  grid-template-areas: "sidebar page";
}

.sidebar {
  grid-area: sidebar;
}

.page {
  grid-area: page;
}

然后调整路由,将侧边栏和页眉组件分别传递给布局路由.

<Routes>
  <Route
    element={
      <DefaultLayout
        sidebar={<DefaultSidebar />}
        header={<DashboardHeader />}
      />
    }
  >
    <Route path="/dashboard">
      <Route path="home" element={<DashboardHomePage />} />
      <Route path="stats" element={<DashboardStatsPage />} />
      <Route path="help" element={<DashboardHelpPage />} />
    </Route>
  </Route>
  <Route
    element={
      <DefaultLayout sidebar={<UserSidebar />} header={<UserHeader />} />
    }
  >
    <Route path="/user">
      <Route path="overview" element={<UserOverviewPage />} />
      <Route path="accounts" element={<UserAccountsPage />} />
    </Route>
  </Route>
</Routes>

Edit how-to-pass-elements-to-other-page-layout-sections-from-inside-a-nested-route

enter image description here enter image description here

Slightly more DRY solution

您可以重构这DefaultLayout个元素,将最外层的div从内侧边栏和第div页元素中分离出来.

const DefaultLayout = () => (
  <div className="layout">
    <Outlet />
  </div>
);
const SidebarHeaderLayout = ({ header, sidebar }) => (
  <>
    <div className="sidebar">{sidebar}</div>
    <div className="page">
      <div className="page-header">{header}</div>
      <div className="page-body">
        <Outlet />
      </div>
    </div>
  </>
);
<Routes>
  <Route element={<DefaultLayout />}>
    <Route
      path="/dashboard"
      element={
        <SidebarHeaderLayout
          sidebar={<DefaultSidebar />}
          header={<DashboardHeader />}
        />
      }
    >
      <Route path="home" element={<DashboardHomePage />} />
      <Route path="stats" element={<DashboardStatsPage />} />
      <Route path="help" element={<DashboardHelpPage />} />
    </Route>
    <Route
      path="/user"
      element={
        <SidebarHeaderLayout
          sidebar={<UserSidebar />}
          header={<UserHeader />}
        />
      }
    >
      <Route path="overview" element={<UserOverviewPage />} />
      <Route path="accounts" element={<UserAccountsPage />} />
    </Route>
  </Route>
</Routes>

Edit how-to-pass-elements-to-other-page-layout-sections-from-inside-a-nested-route (forked)

Typescript相关问答推荐

在角形加载组件之前无法获取最新令牌

Typescript如何从字符串中提取多个文本

Angular 17 -如何在for循环内创建一些加载?

如何防止TypeScript允许重新分配NTFS?

如何创建泛型类型组件来使用React Native的FlatList或SectionList?'

Redux—Toolkit查询仅在不为空的情况下添加参数

在TypeScrip中分配回调时,参数的分配方向与回调本身相反.为什么会这样呢?

泛型函数中输入参数类型的推断问题

TypeScrip表示该类型不可赋值

角效用函数的类型推断

在另一个类型的函数中,编译器不会推断模板文字类型

布局组件中的Angular 17命名路由出口

如何在使用条件类型时使用void

基于泛型的条件接口键

在抽象类属性定义中扩展泛型类型

如何定义这样一个TypeScript泛型,遍历路由配置树并累积路径

TypeScrip:如何缩小具有联合类型属性的对象

任何导航器都未处理有效负载为";params";:{";roomId";:";...";}}的导航操作

获取类属性的类型';TypeScript中的getter/setter

带动态键的 TS 功能