React Router – 如何在根路由中重用我的布局以用于错误元素?

huangapple go评论56阅读模式
英文:

React Router - How can I reuse my layout for the errorElement in the root route?

问题

我正在使用 React Router v6,以下是我的路由配置:

const router = createBrowserRouter([
  {
    path: '/',
    element: <App />,
    errorElement: <ErrorPage />,
    children: [
      {
        index: true,
        element: <HomePage />,
      },
      {
        path: '/sign-up',
        element: <SignUpPage />,
      },
      {
        path: '/log-in',
        element: <LogInPage />,
      },
    ],
  },
]);

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement,
);

root.render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>,
);

App 组件包含我的应用程序布局,并使用 Outlet 组件输出路由元素。但是,如果有错误冒泡到根路由,那么ErrorPage 会按预期显示,但它不会使用 App 的布局...那么,当显示错误页面时,如何重用来自 App 的布局呢?

英文:

I'm using React Router v6 and following are my routes:

const router = createBrowserRouter([
  {
    path: &#39;/&#39;,
    element: &lt;App /&gt;,
    errorElement: &lt;ErrorPage /&gt;,
    children: [
      {
        index: true,
        element: &lt;HomePage /&gt;,
      },
      {
        path: &#39;/sign-up&#39;,
        element: &lt;SignUpPage /&gt;,
      },
      {
        path: &#39;/log-in&#39;,
        element: &lt;LogInPage /&gt;,
      },
    ],
  },
]);

const root = ReactDOM.createRoot(
  document.getElementById(&#39;root&#39;) as HTMLElement,
);

root.render(
  &lt;React.StrictMode&gt;
    &lt;RouterProvider router={router} /&gt;
  &lt;/React.StrictMode&gt;,
);

The App component contains my app's layout and outputs the route elements using the Outlet component. But now if there's an error that bubbles up to the root route, then the ErrorPage gets displayed as expected, but it doesn't make use of the layout from App... So, how can I reuse my layout from App when the error page gets displayed?

答案1

得分: 4

当出现错误时,这有点像是一种要么这样要么那样的情况。要么条件正常,App 组件被渲染,要么存在错误条件,ErrorPage 组件被渲染。

你可以做的是将 App 组件的布局部分抽象成一个独立的布局组件,它可以渲染传递的 children 属性,或者嵌套路由的 Outlet 组件,并在 App 中进行渲染,同时包装 ErrorPage 组件。

示例:

const AppLayout = ({ children }) => (
  ...
  {children ?? <Outlet />}
  ...
);
const App = () => (
  ...
  <AppLayout />
  ...
);
const router = createBrowserRouter([
  {
    path: "/",
    element: <App />, // <-- 使用 Outlet
    errorElement: (
      <AppLayout>     // <-- 使用 children
        <ErrorPage />
      </AppLayout>
    ),
    children: [
      {
        index: true,
        element: <HomePage />
      },
      {
        path: "/sign-up",
        element: <SignUpPage />
      },
      {
        path: "/log-in",
        element: <LogInPage />
      }
    ]
  }
]);

React Router – 如何在根路由中重用我的布局以用于错误元素?

英文:

When there's an error it is kind of an either or kind of scenario. Either conditions are fine and the App component is rendered or there's an error condition and the ErrorPage component is rendered.

What you could do is to abstract the layout portion of the App component into a layout component on its own that can render either a passed children prop or the Outlet component for the nested route, and render it in App and also wrap the ErrorPage component.

Example:

const AppLayout = ({ children }) =&gt; (
  ...
  {children ?? &lt;Outlet /&gt;}
  ...
);
const App = () =&gt; (
  ...
  &lt;AppLayout /&gt;
  ...
);
const router = createBrowserRouter([
  {
    path: &quot;/&quot;,
    element: &lt;App /&gt;, // &lt;-- uses Outlet
    errorElement: (
      &lt;AppLayout&gt;     // &lt;-- uses children
        &lt;ErrorPage /&gt;
      &lt;/AppLayout&gt;
    ),
    children: [
      {
        index: true,
        element: &lt;HomePage /&gt;
      },
      {
        path: &quot;/sign-up&quot;,
        element: &lt;SignUpPage /&gt;
      },
      {
        path: &quot;/log-in&quot;,
        element: &lt;LogInPage /&gt;
      }
    ]
  }
]);

React Router – 如何在根路由中重用我的布局以用于错误元素?

huangapple
  • 本文由 发表于 2023年6月2日 03:13:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76385016.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定