子页面与react-router 4

时间:2017-10-03 15:36:56

标签: javascript node.js reactjs react-router react-router-dom

我的路由器设置如下

<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 />

1 个答案:

答案 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来查找路径,这些路径仅迭代直接子项,而不是嵌套子项。