React Router Dom V6 将数组传递给路径

问题描述 投票:0回答:7

我想在react-router-dom v6中通过多个路由渲染同一页面,就像在v5中一样。 但是,我找不到有效的方法来做到这一点。

v5 中的示例我可以这样做:

    <BrowserRouter>
      <Switch>
        <Route path={["/dashboard", "/home"]} render={<Home />} />
        <Route path="/other" render={<OtherPage/>} />
        <Route path={["/", "/404"]} render={<NotFound />} />
      </Switch>
    </BrowserRouter>

但是在 v6 中,据说

path
需要是 string

我发现实现这一目标的唯一方法是将它们分开,如下所示:

    <BrowserRouter>
      <Routes>
        <Route path="/dashboard" element={<Home />} />
        <Route path="/home" element={<Home />} />
      </Routes>
    </BrowserRouter>

这意味着我必须写

<Home />
多次

我想保持我的代码尽可能干净。

我查了官方文档,但没有提到这部分。我做了研究,但找不到解决方案。

reactjs react-router-dom
7个回答
12
投票

无需定制解决方案。最干净的解决方案是内部循环:

<Routes>
  {["/dashboard", "/home"].map(path => (
    <Route 
      key="Home" // optional: avoid full re-renders on route changes
      path={path}
      element={<Home />}
    />
  ))}
</Routes>

对于只有两条路线的用例,我个人认为拥有单独的路线更具可读性。但对于我的用例来说;我有 6 个以上的路由指向同一个组件,它不再有意义了。

关键道具

固定的

key
是一种“黑客”,仅在用户可以在内部和/或组件很重的情况下在 URL 之间切换的特定情况下才需要。对数组中的所有路由使用相同的
key
告诉 React,当 React Router 切换路由时,组件没有卸载,并且只有 props 发生了变化,这样 React 就不会重新渲染整个分支。它之所以有效,是因为 React Router v6 永远不会在任何时间点渲染两条路由。

游乐场

https://stackblitz.com/edit/github-otdpok?file=src/App.tsx


6
投票

我创建了这个辅助函数,它可以在 React Router v6 中运行:

const renderMultiRoutes = ({ element: Element, paths, ...rest }: MultiRoutes) =>
  paths.map((path) => <Route key={path} path={path} {...rest} element={Element} />);

然后我可以执行以下操作:

<Routes>
  {renderMultiRoutes({
    paths: ['/', '/dashboard'],
    element: <Feature />,
  })}
</Routes>

1
投票

结果我降级到了 v5。 然而,这是一个基于@MikeAbeln 的观点

map
的解决方案。 我构建了一个包装组件来实现这个目的。

import { Route } from 'react-router-dom';

export default function MultiRoute({ element: Element, path: paths, ...rest }) {
    return (
        <>
            {Array.isArray(paths) ? paths.map((path) =>
                <Route path={path} {...rest} element={props => <Element {...props} />} />
            ) :
                <Route path={paths} {...rest} element={props => <Element {...props} />} />
            }
        </>
    );
}

然后我可以按照以下步骤使我的 Routes.js 文件足够干净且易于扩展:

    <BrowserRouter>
      <Routes>
        <MultiRoute path={["/dashboard", "/home"]} element={<Home />} />
        <MultiRoute path="/other" element={<OtherPage/>} />
        <MultiRoute path={["/", "/404"]} element={<NotFound />} />
      </Routes>
    </BrowserRouter>

更新

这将返回错误“错误:[MultiRoute] 不是组件。其所有子组件必须是 a 或 ”,如 @Drew Reese 提到的。 需要修复

请在下面评论或留下答案并提前致谢。


0
投票

我也遇到过类似的情况。我有一些不同的路线应该呈现相同的页面布局。在 v5 中,它的实现为:

<Switch>
    <Route
      exact
      path={[
        ROOT_ROUT,
        SIGN_UP_ROUT,
        FORGOT_PASSWORD_ROUT,
        CHANGE_FORGOT_PASSWORD_ROUT,
      ]}
    >
      <AuthPageTemplate>
        <Switch>
          <Route exact path="/" component={SignIn} />
          <Route exact path="/sign-up" component={SignUp} />
          <Route exact path="/forgot-password" component={ForgotPassword} />
          <Route
            exact
            path="/change-forgot-password/:code"
            component={ChangeForgotPassword}
          />
        </Switch>
      </AuthPageTemplate>
    </Route>
    <Route component={Page404} />
  </Switch>

更新此代码后解决了相同的任务:

<Routes>
  <Route
    path="/"
    element={
      <AuthPageTemplate>
        <Outlet />
      </AuthPageTemplate>
    }
  >
    <Route index element={<SignIn />} />
    <Route path="/sign-up" element={<SignUp />} />
    <Route path="/forgot-password" element={<ForgotPassword />} />
    <Route
      path="/change-forgot-password/:code"
      element={<ChangeForgotPassword />}
    />
  </Route>
  <Route path="*" element={<Page404 />} />
</Routes>

对我来说效果很好。


0
投票

对我来说这适用于react-router-dom v6

<Routes>
    <Route path='/' element={<Navigate to="/search" />} />
    <Route exact path='/videos' element={<Results />} />
    <Route exact path='/news' element={<Results />} />
    <Route exact path='/images' element={<Results />} />
    <Route exact path='/search' element={<Results />} />
</Routes>

0
投票

我在创建项目时遇到类似的问题: 简单的解决方案是映射所有路径:

解决方案如下:

<BrowserRouter>
      <Switch>
        <Route path={["/videos", "/images","/news"]} render={<Result />} />
      </Switch>
    </BrowserRouter>

现在我们必须将此代码转换为

react-router-dom
v6:

<BrowserRouter>
      <Routes>
        {['/images','/videos','/news'].map(path => (
          <Route key={path} path={path} element={<Result />}
))}
      </Routes>
</BrowserRouter>

0
投票
{["/exstv", "/exstv/:id"]?.map((item) => {
    return <Route path={item} element={<SportsTv />}></Route>
 })}
© www.soinside.com 2019 - 2024. All rights reserved.