React Router v5.0 嵌套路由 [英] React Router v5.0 Nested Routes
问题描述
我正在构建一个 React 应用程序,但无法使路由正常工作.
我需要一个通用布局(页眉、页脚)用于一些身份验证路由(
/login
、sign-up
、forgot-password
等...)而且我需要为应用程序的其余受保护部分(
Home
、Dashboard
等...)使用另一个通用布局我需要另一个没有任何布局的 404 页面.
我尝试了这些链接中的几种技术:
- 使用 React Router v4 的多个布局
- https://simonsmith.io/reusing-layouts-in-react-路由器-4
- 反应路由器 v4/v5 的嵌套路由
- https://reacttraining.com/react-router/web/example/路由配置
但可以达到工作版本.
这是我目前拥有的:
(注意:现在我忽略了阻止非登录用户进入 AppLayout 的私有路由的需要,我会在之后处理)
const 应用程序:React.FC = () =>{const 历史 = createBrowserHistory();返回 (<div className="应用程序"><路由器历史={历史}><开关><应用布局><Route path="/home" component={HomePage}/><Route path="/dashboard" 组件={DashboardPage}/>...</AppLayout><AuthLayout><Route path="/login" component={LoginPage}/><Route path="/sign-up" component={SignUpPage}/>...</AuthLayout><Route path="*" component={NotFoundPage}/></开关></路由器>
);};导出默认应用程序;
AuthLayout
和 AppLayout
都很简单并且与此类似(只是每个页眉/页脚不同):
class AppLayout 扩展组件 {使成为() {返回 (<div className="AppLayout"><header>...</header>{this.props.children}<页脚>...</页脚>
);}}导出默认的 AppLayout;
问题是只呈现来自 AppLayout 的路由.其他路由只显示 AppLayout header
和 footer
而没有任何内容.
这些是我正在使用的 React 版本:
"react": "^16.8.6","react-dom": "^16.8.6","react-router-dom": "^5.0.0",
任何帮助将不胜感激.
提前致谢.
我花了一些时间才找到我喜欢的答案.@johnny-peter 和@gaurab-kc 解决方案很棒,他们让我了解 React 的路由机制.
@johnny-peter 的解决方案的缺点是强迫我为 /auth/...
下的所有 auth
相关路由添加前缀(例如 /auth/login
& auth/sign-up
) 我不想要.
@gaurab-kc 解决方案只支持一组路由.所以如果用户已经注册,他就不能再访问 /login
路由.
直到最近,我使用了自己的解决方案,该解决方案存在破坏了通用页眉和页脚的全部目的"的问题.正如@johnny-peter 所提到的,它应该被否决了几次.
现在我正在使用另一种解决方案:
<开关><完全重定向 from="/" to="/home"/><路由精确路径={["/login", "/sign-up", ...]}><AuthLayout><开关><路线路径=/登录"组件={登录页面}/><路线路径=/注册"组件={注册页面}/></开关></AuthLayout></路线><路由精确路径={[/家",/仪表盘",...]}><网站布局><开关><路线路径=/家"组件={主页}/><路线路径=/仪表板"组件={仪表板页面}/></开关></站点布局></路线><Route path="*" component={NotFoundPage}/></开关></路由器>
这可以防止上述所有缺点.它允许我:
- 为每个部分使用布局,在路线更改时不会重新渲染.
- 不会强迫我为路由添加任何前缀.
- 所有路由同时工作,让用户无需先注销即可路由回
/login
或其他auth
路由.
此解决方案的唯一缺点是代码较多且路线重复,但我愿意为此付出代价.
I'm building a react app and I can't make the routing work.
I need one common layout (header, footer) for a few Auth routes (
/login
,sign-up
,forgot-password
, etc...)And I need need another common layout for the rest of the protected parts of the app (
Home
,Dashboard
, etc...)I need another 404 page without any layout.
I've tried several techniques from those links:
- Multiple Layouts with React Router v4
- https://simonsmith.io/reusing-layouts-in-react-router-4
- Nested routes with react router v4 / v5
- https://reacttraining.com/react-router/web/example/route-config
But could reach working version.
This is what I'm currently have:
(Note: for now I'm ignoring the need to block non logged-in users into the private routes of AppLayout, I'll handle that right after)
const App: React.FC = () => {
const history = createBrowserHistory();
return (
<div className="App">
<Router history={history}>
<Switch>
<AppLayout>
<Route path="/home" component={HomePage}/>
<Route path="/dashboard" component={DashboardPage}/>
...
</AppLayout>
<AuthLayout>
<Route path="/login" component={LoginPage}/>
<Route path="/sign-up" component={SignUpPage}/>
...
</AuthLayout>
<Route path="*" component={NotFoundPage} />
</Switch>
</Router>
</div>
);
};
export default App;
Both AuthLayout
and AppLayout
are simple and similar to that (just with different header/footer for each):
class AppLayout extends Component {
render() {
return (
<div className="AppLayout">
<header>...</header>
{this.props.children}
<footer>...</footer>
</div>
);
}
}
export default AppLayout;
The problem is that only routes from the AppLayout are rendered.
Other routes just showing the AppLayout header
and footer
without any content.
Those are the react versions I'm using:
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-router-dom": "^5.0.0",
Any help would be appreciated.
Thanks in advance.
It took me some time to find the answer that I favoured. Both @johnny-peter & @gaurab-kc solutions were great and they tought me about React's routing mechanism.
@johnny-peter 's solution had disadvantage of forcing me to put a prefix for all auth
related routes under /auth/...
(e.g. /auth/login
& auth/sign-up
) which I didn't wanted.
@gaurab-kc solution was supporting only one set of routes.. so if user was already signed up, he couldn't visit the /login
route anymore.
Up till recently I used my own solution which had the problem of "defeating the whole purpose of a common header and footer." as @johnny-peter mentioned and it was down-voted few times as it should be.
Now I'm using another solution:
<Router history={browserHistory}>
<Switch>
<Redirect exact from="/" to="/home"/>
<Route exact path={["/login", "/sign-up", ...]}>
<AuthLayout>
<Switch>
<Route
path="/login"
component={LoginPage}
/>
<Route
path="/sign-up"
component={SignUpPage}
/>
</Switch>
</AuthLayout>
</Route>
<Route exact path={[
"/home",
"/dashboard",
...
]}>
<SiteLayout>
<Switch>
<Route
path="/home"
component={HomePage}
/>
<Route
path="/dashboard"
component={DashboardPage}
/>
</Switch>
</SiteLayout>
</Route>
<Route path="*" component={NotFoundPage}/>
</Switch>
</Router>
which prevents all the above disadventages. It's allows me to:
- Use a layout for each section which isn't re-rendered on route change.
- Doesn't forcing me to add any prefix to routes.
- All routes are working at the same time, letting users to route back into the
/login
or otherauth
routes without logout first.
The only disadvantage of this solution is having more code and duplicating the routes, but it's a cost I'm willing to pay.
这篇关于React Router v5.0 嵌套路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!