代码之家  ›  专栏  ›  技术社区  ›  DisLido

如何在splat路由中使用react-router-Link?

  •  1
  • DisLido  · 技术社区  · 5 月前

    我有一个这样的路由器

    import { createRoot } from 'react-dom/client';
    // react-router v7
    import { createHashRouter, Link, Outlet, RouterProvider } from 'react-router';
    
    const root = document.createElement('div');
    root.setAttribute('id', 'app');
    document.body.appendChild(root);
    
    const router = createHashRouter([
      {
        path: 'homepage',
        element: (
          <div>
            <Link to="workspace/1">To workspace 1</Link>
            <br />
            <Link to="foo">To foo</Link>
            <main>
              <Outlet />
            </main>
          </div>
        ),
        children: [
          {
            path: 'workspace/:spaceId/*',
            // I want to lazy load this route, so I use <Routes> to define its sub routes
            element: (
              <div>
                <Link to="setting">To space setting</Link>
                <Routes>
                  <Route path="setting" />
                </Routes>
              </div>
            ),
          },
          {
            path: 'foo',
            element: <div>foo</div>,
          },
        ],
      },
    ]);
    createRoot(root).render(
      <RouterProvider router={router} />,
    );
    

    这个 <Link> 在主页上工作得很好。但是,当我多次单击“到空间设置”链接时,路径变为 /homepage/workspace/1/setting/setting/setting... .

    我不想在链接g中写绝对路径。 <Link to="/homepage/workspace/${spaceId}/setting" /> 。是否有更好的方法来解决这个问题?

    我试过:

    • 在中定义子路线 createHashRouter 为了去除飞溅 <链接> 工作得很好。但这不是我想要的。
    • 获取路线的当前路径,以便我可以使用 <Link to={`${currentPath}/setting`} /> ,但我在中找不到这样做的api react-router .
    1 回复  |  直到 5 月前
        1
  •  1
  •   Drew Reese    5 月前

    在React Router v7 CHANGELOG和文档中进行了一些挖掘,但从RR6到RR7的迁移路径是相对路径( v7_relativeSplatPath 特征标志)相对简单。

    https://reactrouter.com/upgrading/v6#v7_relativesplatpath

    • 拆分 <Route> 分成两部分

      分割任何多段飞溅 <路线> 进入父路线 路径和儿童路线与飞溅

      老的

      {
        path: 'workspace/:spaceId/*',
        element: (
          <div>
            <Link to="setting">To space setting</Link>
            <Routes>
              <Route path="setting" />
            </Routes>
          </div>
        ),
      },
      

      当前:

      {
        path: "workspace/:spaceId",
        children: [
          {
            path: "*",
            element: (
              <div>
                <Link to="setting">To space setting</Link>
                <Routes>
                  <Route path="setting" element={<h1>Setting</h1>} />
                </Routes>
              </div>
            ),
          },
        ],
      },
      
    • 更新相关链接

      更新任何 <Link> 该路线树中的元素,以包括额外的 .. 继续链接到同一位置的相对分段

      老的

      <Link to="setting">To space setting</Link>
      

      当前:

      <Link to="../setting">To space setting</Link>
      

    最后一个关键是让后代路由元素也精确地呈现在 "/homepage/workspace/:spaceId" 为此,请制作 "workspace/:spaceId" 路线也是一条索引路线。

    最终代码:

    const router = createHashRouter([
      {
        path: "homepage",
        element: (
          <div>
            <Link to="workspace/1">To workspace 1</Link>
            <br />
            <Link to="foo">To foo</Link>
            <main>
              <Outlet />
            </main>
          </div>
        ),
        children: [
          {
            path: "workspace/:spaceId",
            children: [
              {
                index: true,
                path: "*",
                element: (
                  <div>
                    <Link to="../setting">To space setting</Link>
                    <Routes>
                      <Route path="setting" element={<h1>Setting</h1>} />
                    </Routes>
                  </div>
                ),
              },
            ],
          },
          {
            path: "foo",
            element: <div>foo</div>,
          },
        ],
      },
    ]);