Flo*_*elt 35 reactjs react-router
我想在我的公共布局中渲染我的一些路线,以及我的私人布局中的其他一些路线,是否有一个干净的方法来做到这一点?
示例显然不起作用,但我希望大致解释我正在寻找的内容:
<Router>
<PublicLayout>
<Switch>
<Route exact path="/" component={HomePage} />
<Route exact path="/about" component={AboutPage} />
</Switch>
</PublicLayout>
<PrivateLayout>
<Switch>
<Route exact path="/profile" component={ProfilePage} />
<Route exact path="/dashboard" component={DashboardPage} />
</Switch>
</PrivateLayout>
</Router>
Run Code Online (Sandbox Code Playgroud)
我想要切换某些路由的布局,如何使用新的路由器做到这一点?
嵌套路由不再有效,并给我这个错误:
You should not use <Route component> and <Route children> in the same route; <Route children> will be ignored
Run Code Online (Sandbox Code Playgroud)
编辑:布局包装整个路径组也意味着只要您保留在同一个私有/公共路由组中,这些布局只会呈现一次.如果您的布局必须从您的服务器获取某些内容,这是一个大问题,因为如果您使用布局包装每个页面,那么每次更改都会发生这种情况.
Zap*_*ree 28
我为此做的是创建一个简单的组件,为Route组件添加一个额外的属性,即布局:
function RouteWithLayout({layout, component, ...rest}){
return (
<Route {...rest} render={(props) =>
React.createElement( layout, props, React.createElement(component, props))
}/>
);
}
Run Code Online (Sandbox Code Playgroud)
那么在您的情况下,您的路线将如下所示
<Switch>
<RouteWithLayout layout={PublicLayout} path="/" component={HomePage}/>
<RouteWithLayout layout={PublicLayout} path="/about" component={AboutPage}/>
<RouteWithLayout layout={PrivateLayout} path="/profile" component={ProfilePage}/>
<RouteWithLayout layout={PrivateLayout} path="/dashboard" component={DashboardPage}/>
</Switch>
Run Code Online (Sandbox Code Playgroud)
Seb*_*rin 15
找到后,干净有效的方式(避免滥用重新渲染):
<Route exact path={["/about", "/"]}>
<PublicLayout>
<Route exact path="/" component={HomePage} />
<Route path="/about" component={AboutPage} />
</PublicLayout>
</Route>
<Route path={["/profile", "/dashboard"]}>
<PrivateLayout>
<Route path="/profile" component={ProfilePage} />
<Route path="/dashboard" component={DashboardPage} />
</PrivateLayout>
</Route>
Run Code Online (Sandbox Code Playgroud)
同样,它可以重构,请参阅我的完整答案:https : //stackoverflow.com/a/57358661/3437790
如果你正在使用Typescript并希望遵循这个反应布局方法,那么你可以像这样声明你的布局:
import './Default.less';
import React from 'react';
import { Route } from "react-router-dom";
import { Sider } from './Components';
import { Notification } from 'Client/Components';
interface IDefaultProps {
component: any
path?: string;
exact?: boolean;
}
const Default: React.SFC<IDefaultProps> = (props) => {
const { component: Component, ...rest } = props;
return <Route {...rest} render={matchProps => (
<div className="defaultLayout">
<Sider />
<div className="defaultLayoutContent">
<Component {...matchProps} />
</div>
<Notification />
</div>
)} />
}
export default Default;
Run Code Online (Sandbox Code Playgroud)
并声明这样的路线:
import React from 'react';
import { Route } from 'react-router-dom';
import { DefaultLayout } from 'Client/Layout';
import { Dashboard, Matters, Schedules, Students } from './Containers';
export const routes = <div>
<DefaultLayout exact path="/" component={Dashboard} />
<DefaultLayout path="/matters" component={Matters} />
<DefaultLayout path="/schedules" component={Schedules} />
<DefaultLayout path="/students" component={Students} />
</div>;
Run Code Online (Sandbox Code Playgroud)
我认为布局不属于路线文件。
保持路线清洁,即:
<Route exact path="/" component="HomePage" />
Run Code Online (Sandbox Code Playgroud)
然后,在HomePage组件中,将渲染的内容包装在您选择的布局中:
...
render() {
<PublicLayout>
<h1>Home page!</h1>
</PublicLayout>
}
Run Code Online (Sandbox Code Playgroud)
这样,路由就可以保持超级干净,此外,您还可以通过一种简单的方法来显示应该同时支持两种布局的路由(例如404页)。
我会在任何被问到这个问题的地方写这个,如果你在其他地方看到过,很抱歉。我这样做只是因为我已经挣扎了一段时间,我认为尽可能多地传播这个解决方案是值得的。够了,这就是我所做的,我认为这是不言自明的。就像一个魅力,它很容易打字。
const withLayout = (LayoutComp, ComponentComp) => <LayoutComp><ComponentComp /></LayoutComp>;
const withDefaultLayout = (ComponentComp) => () => withLayout(Layout, ComponentComp);
const withEmptyLayout = (ComponentComp) => () => withLayout(EmptyLayout, ComponentComp);
export const routes = <div>
<Switch>
<Route path="/" exact render={withDefaultLayout(Home)} />
<Route path='/subscriptions' render={withDefaultLayout(SubscriptionsWrapped)} />
<Route path='/callback' render={withEmptyLayout(AuthCallback)} />
<Route path='/welcome/initial' render={withEmptyLayout(Start)} />
</Switch>
</div>;
Run Code Online (Sandbox Code Playgroud)
更新:我用另一种方式解决了这个问题,但是如果强制您使用 /app 或 /admin 为应用程序的不同部分命名。
UserRoutes、AdminRoutes 和 PublicRoutes 中的每个组件基本上都是大型 Switch 组件,其根部具有特定布局。
它看起来是这样的:
<Router>
<Switch>
<Route path="/app" render={props => <UserRoutes {...props} />} />
<Route path="/admin" render={props => <AdminRoutes {...props} />} />
<Route path="/" render={props => <PublicRoutes {...props} />} />
</Switch>
</Router>
Run Code Online (Sandbox Code Playgroud)
旧:一种解决方案是使用每个 Route 的 render prop,但这看起来确实很麻烦:
<Router>
<Switch>
<Route
path="/"
render={() => <PublicLayout><HomePage /></PublicLayout>}
/>
<Route
path="/about"
render={() => <PublicLayout><AboutPage /></PublicLayout>}
/>
<Route
path="/profile"
render={() => <PrivateLayout><ProfilePage /></PrivateLayout>}
/>
<Route
path="/dashboard"
render={() => <PrivateLayout><DashboardPage /></PrivateLayout>}
/>
</Switch>
</Router>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14340 次 |
| 最近记录: |