我的路由器设置如下
<Switch>
<PrivatePage key={index} {...opts} component={(props) =>
<Section {...props} pages={childRoutes} />
} />
<PrivatePage path='/accounts/:id' exact={true} render={({ match }) => (
<Redirect to={/accounts/${match.params.id}/profile} />
)} />
...
<Route component={NotFound} />
</Switch>
然后<Section />
<SubNavMenu />
<Route path=/accounts/:id/profile componet={ProfilePage} />
<Route path=/accounts/:id/dashboard componet={DashboardPage} />
然后<PrivatePage />
呈现,而<Page />
只呈现<Navigation /> {this.props.children}
const PrivatePage = ({ component: Component, ...rest }) => {
let result = props => (
<Redirect
to={{
pathname: '/redirect',
state: { from: props.location },
}}
/>
)
if (User.methods.isAuthed()) {
result = props => (
<Page>
<Component {...props} />
</Page>
)
} else if (rest.path === '/') {
result = props => (
<Redirect
to={{
pathname: '/login',
}}
/>
)
}
return <Route {...rest} render={props => result(props)} />
}
export default PrivatePage
点击带我到accounts/:id
的链接可以正确地将我重定向到个人资料页面,但是当我尝试从SubNavMenu转到仪表板页面时,我得到了我的NotFound页面并安慰了this.props.match {{ 1}}但我的路径是{path: "/", url: "/", params: {…}, isExact: false}
感谢您的帮助
按要求,部分
的完整代码/accounts/7kB7fRdsu39Be44ou/dashboard
pages = [
{
authed: true,
icon: 'cog',
component: (<div/>),
name: 'AccountDetailSection',
path: `/accounts/:id/profile`,
},
{
authed: true,
component: AccountProfilePage,
exact: true,
getLink: id => `/accounts/${id}/profile`,
icon: 'cog',
label: 'Account',
name: 'AccountDetailProfile',
parent: 'AccountDetailSection',
path: `/accounts/:id/profile`,
},
{
authed: true,
component: AccountDashboardsPage,
exact: true,
getLink: id => `/accounts/${id}/dashboard`,
icon: 'cog',
label: 'Dashboard',
name: 'AccountDetailDashboards',
parent: 'AccountDetailSection',
path: `/accounts/:id/dashboard`,
},
]
class PrivateSection extends React.Component<IProps, IState> {
classes = { // static values
button: 'App-navigation--listItemButton',
container: 'App-navigation',
header: 'App-navigation--header',
headerLogo: 'App-navigation--headerLogo',
listContainer: 'App-navigation--list',
listItem: 'App-navigation--listItem',
listItemActive: 'App-subnavigation--listItem--active',
listItemHover: 'App-navigation--listItem--hover',
positionBottom: 'App-navigation--bottom',
positionTop: 'App-navigation--top',
}
sharedProps = { // static values
activeClass: this.classes.listItemActive,
buttonClass: this.classes.button,
buttonContainer: this.classes.listItem,
hoverClass: this.classes.listItemHover,
menuContainer: this.classes.listContainer,
onHover: this.handleMouseIn.bind(this),
}
constructor(props: IProps) {
super(props)
this.state = {
hovering: '',
}
}
handleMouseIn(name: string) {
this.setState({hovering: name})
}
handleMouseOut() {
this.setState({hovering: ''})
}
renderSubNav() {
const navOpts = {
hovering: this.state && this.state.hovering || '',
onHover: this.handleMouseIn.bind(this),
}
const navItems: any = this.props.pages.map(p => { // tslint:disable-line no-any
const o = {...p}
if (typeof(o.getLink) === 'function') {
const {id} = this.props.match && this.props.match.params || {id: ''}
o.link = o.getLink(id)
o.getLink = undefined
}
o.authed = undefined
o.exact = undefined
o.component = undefined
return {...navOpts, ...o}
})
const submenuClasses = {
active: this.sharedProps.activeClass,
button: this.sharedProps.buttonClass,
buttonContainer: this.sharedProps.buttonContainer,
hover: this.sharedProps.hoverClass,
menuContainer: this.sharedProps.menuContainer,
}
return (
<div
className='profile_subnav'
style={{height: '100%'}}
onMouseLeave={() => this.handleMouseOut()}
>
<Menu
items={navItems}
classes={submenuClasses}
/>
</div>
)
}
renderContent() {
return (
<div className='profile_content'>
{this.props.pages.map((opts, index) => {
const o: any = {...opts} // tslint:disable-line no-any
if (typeof(o.getLink) === 'function') {
const {id} = this.props.match && this.props.match.params || {id: ''}
o.link = o.getLink(id)
o.getLink = undefined
}
return (
<PrivateRoute key={index} {...o}/>
)
})}
</div>
)
}
render() {
return (
<div
className='page--content_container'
>
{this.renderSubNav()}
{this.renderContent()}
</div>
)
}
}
export default PrivateSection
的渲染方法(由<Button />
包裹
<Menu />
答案 0 :(得分:1)
我遇到类似的问题,其中Switch没有找到用其他组件包装的路由。查看源代码,看起来Switch
不在递归中查找子项中的Route
,因此它们无法嵌套。
在这种情况下,要使用Switch
,您需要重构以使Route
成为每条路线的顶级组件。或重构不使用Switch
- 基本上使所有路线exact
匹配。
切换来源:https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/Switch.js
它使用React.Children.forEach
来查找路径,这些路径仅迭代直接子项,而不是嵌套子项。