Home  >  Q&A  >  body text

React Router v6: Unable to correctly capture "*" characters in all paths problem solution

<p>我有以下两个文件</p> <p><strong>AppRoutes.tsx</strong></p> <pre class="brush:php;toolbar:false;">import { Route, Routes } from "react-router-dom"; import NotFound from "../pages/NotFound"; import MessageRoutes from "../features/messages/routes/MessageRoutes"; import Home from "../pages/Home"; export default function AppRoutes() { return ( <Routes> <Route path="/" element={<Home />} /> <Route path="/messages/*" element={<MessageRoutes />} /> <Route path="*" element={<NotFound />} /> </Routes> ); }</pre> <p><strong>MessageRoutes.tsx</strong></p> <pre class="brush:php;toolbar:false;">import { Route, Routes } from "react-router-dom"; import ProtectedRoutes from "../../../routes/ProtectedRoutes"; import MessageOverview from "../pages/MessageOverview"; import NewMessage from "../pages/NewMessage"; export default function MessageRoutes() { return ( <Routes> <Route element={<ProtectedRoutes />}> <Route path="/" element={<MessageOverview />} /> <Route path="/new" element={<NewMessage />} /> </Route> </Routes> ); }</pre> <p>因为我使用路径 "/messages/*" 来捕获以 /messages 开头的所有路径,所以我的 MessageRoutes 组件负责处理这些嵌套路由。我在 AppRoutes 组件中有一个最终的 "*" 路由来捕获应用程序不支持的任何 URL。但是如果路径是 "/messages/loremipsum",react router 不会捕获 NotFound 路由,因为以 "/messages" 开头的所有内容都将由 MessageRoutes 组件处理。</p> <p>这是否意味着在每个嵌套路由组件中,我现在都必须再次添加一个最终的 <code><route path="*" element="{<NotFound" ="">} /></route></code>,以支持最终的捕获所有路由?我不喜欢这种方法。难道没有绝对的最终捕获所有路由的方法吗?</p>
P粉579008412P粉579008412443 days ago454

reply all(1)I'll reply

  • P粉458913655

    P粉4589136552023-08-26 17:20:32

    Yes, absolutely. Each Routes component manages the "scope" of routes it can match. For example, if the current URL path is "/messages/loremipsum", the root Routes component will match "/messages/*" and render ## correctly #MessageRoutesComponent. Then, the Routes component of the MessageRoutes component will continue to match the next path segment. Since there is no routing path for "*/loremipsum", you need another "catch-all" route to handle this.

    The problem is that the

    Routes component is not aware of the descendant routes that any of its routes may render.

    Example:

    import { Route, Routes } from "react-router-dom";
    import NotFound from "../pages/NotFound";
    import MessageRoutes from "../features/messages/routes/MessageRoutes";
    import Home from "../pages/Home";
    
    export default function AppRoutes() {
      return (
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/messages/*" element={<MessageRoutes />} />
          <Route path="*" element={<NotFound />} />
        </Routes>
      );
    }
    import { Route, Routes } from "react-router-dom";
    import ProtectedRoutes from "../../../routes/ProtectedRoutes";
    import MessageOverview from "../pages/MessageOverview";
    import NewMessage from "../pages/NewMessage";
    import NotFound from "../pages/NotFound";
    
    export default function MessageRoutes() {
      return (
        <Routes>
          <Route element={<ProtectedRoutes />}>
            <Route path="/" element={<MessageOverview />} />
            <Route path="/new" element={<NewMessage />} />
            <Route path="*" element={<NotFound />} />
          </Route>
        </Routes>
      );
    }

    If you want a separate "catch-all" route, then you need a separate route configuration.

    Example:

    import { Route, Routes } from "react-router-dom";
    import MessageOverview from "../pages/MessageOverview";
    import NewMessage from "../pages/NewMessage";
    import NotFound from "../pages/NotFound";
    import Home from "../pages/Home";
    
    export default function AppRoutes() {
      return (
        <Routes>
          <Route path="/" element={<Home />} />
          <Route element={<ProtectedRoutes />}>
            <Route path="/messages">
              <Route index element={<MessageOverview />} />
              <Route path="new" element={<NewMessage />} />
            </Route>
          </Route>
          <Route path="*" element={<NotFound />} />
        </Routes>
      );
    }

    Now, when the URL path is

    "/messages/loremipsum", the Routes component knows the embed it is rendering Set routing, and can correctly match and render NotFound.

    reply
    0
  • Cancelreply