我想在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 />
多次。
我想保持我的代码尽可能干净。
我查了官方文档,但没有提到这部分。我做了研究,但找不到解决方案。
无需定制解决方案。最干净的解决方案是内部循环:
<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 永远不会在任何时间点渲染两条路由。
我创建了这个辅助函数,它可以在 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>
结果我降级到了 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 或
请在下面评论或留下答案并提前致谢。
我也遇到过类似的情况。我有一些不同的路线应该呈现相同的页面布局。在 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>
对我来说效果很好。
对我来说这适用于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>
我在创建项目时遇到类似的问题: 简单的解决方案是映射所有路径:
<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>
{["/exstv", "/exstv/:id"]?.map((item) => {
return <Route path={item} element={<SportsTv />}></Route>
})}