【问题标题】:Render a 404 page on its own without any other components with React Router使用 React Router 自行渲染 404 页面,无需任何其他组件
【发布时间】:2022-10-11 01:05:14
【问题描述】:

我正在使用reacter-router-dom@6.4.2,我有以下代码:

索引.tsx

const container = document.getElementById("app")!;
const root = createRoot(container);

root.render(
  <React.StrictMode>
    <Provider store={store}>
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<App />} />
          <Route path="*" element={<NotFound />} />
        </Routes>
      </BrowserRouter>
    </Provider>
  </React.StrictMode>
);

reportWebVitals();

而在我的应用程序.tsx我有:

const App = () => {
  return (
    <>
      <Sidebar />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="patients/:patient" element={<Patient />}>
          <Route path="overview" element={<Overview />} />
        </Route>
      </Routes>
    </>
  );
};

export default App;

在 Chrome 控制台中,我收到以下警告:

utils.ts:767 You rendered descendant <Routes> (or called `useRoutes()`) at "/" (under <Route path="/">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.

Please change the parent <Route path="/"> to <Route path="*">.

为什么我会收到此警告,我该如何解决?

即使我从App.tsx 中删除&lt;Route path="/" element={&lt;Home /&gt;} /&gt;,我仍然会收到警告

现在,只有 / 路由有效。它呈现&lt;Sidebar /&gt;&lt;Home /&gt; 组件。但是如果我去http://localhost:3000/patients/blah/overview 我得到&lt;NotFound /&gt; 组件,而我应该得到&lt;Overview /&gt; 组件(至少那是我想要得到的)

【问题讨论】:

    标签: reactjs typescript react-router react-router-dom


    【解决方案1】:

    App 组件正在渲染后代路由,因此父路由应在其路由中附加一个尾随 "*" 通配符匹配器。

    例子:

    const container = document.getElementById("app")!;
    const root = createRoot(container);
    
    root.render(
      <React.StrictMode>
        <Provider store={store}>
          <BrowserRouter>
            <Routes>
              <Route path="/*" element={<App />} />
              <Route path="*" element={<NotFound />} />
            </Routes>
          </BrowserRouter>
        </Provider>
      </React.StrictMode>
    );
    

    要处理“未知”路由,后代Routes 组件必然需要渲染另一个NotFound 路由。

    const App = () => {
      return (
        <>
          <Sidebar />
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="patients/:patient" element={<Patient />}>
              <Route path="overview" element={<Overview />} />
            </Route>
            <Route path="*" element={<NotFound />} />
          </Routes>
        </>
      );
    };
    

    如果App 组件真的只是作为“布局路线”来渲染具有特定路线的Sidebar 组件,那么我建议将其转换为实际的布局路线。

    import { Outlet } from 'react-router-dom';
    
    const AppLayout = () => {
      return (
        <>
          <Sidebar />
          <Outlet />
        </>
      );
    };
    

    ...

    const container = document.getElementById("app")!;
    const root = createRoot(container);
    
    root.render(
      <React.StrictMode>
        <Provider store={store}>
          <BrowserRouter>
            <Routes>
              <Route element={<AppLayout />}>
                <Route path="/" element={<Home />} />
                  <Route path="patients/:patient" element={<Patient />}>
                  <Route path="overview" element={<Overview />} />
                </Route>
              </Route>
              <Route path="*" element={<NotFound />} />
            </Routes>
          </BrowserRouter>
        </Provider>
      </React.StrictMode>
    );
    

    【讨论】:

    • 谢谢@DrewReese,如果我这样做并导航到/calendar,我会在我期望&lt;NotFound /&gt; 时得到&lt;Sidebar /&gt;
    • @J86 对于后代路由,每个后代 Routes 组件需要呈现自己的“未知”路由。如果您转换为使用布局路由和嵌套路由,则单个 Routes 组件会处理所有路由路径匹配。
    • 谢谢,诀窍在于创建布局路线。非常感谢德鲁 <3
    猜你喜欢
    • 2018-07-11
    • 1970-01-01
    • 2016-05-29
    • 2018-02-02
    • 2018-01-11
    • 2017-08-31
    • 2017-11-14
    • 1970-01-01
    • 2020-09-04
    相关资源
    最近更新 更多