React-Router v4 嵌套路由不匹配

React-Router v4 Nested Route Not Matching

我是 React Router 的新手,正在努力理解为什么我的实现不起作用。在 DevTools 中,嵌套路由似乎已创建,但是当我单击应该加载它的 link 时,整个页面反而重新呈现为空白。我猜测 link 的 URL 与路线的路径不匹配(尽管从屏幕截图中可以看出,它们是相同的)或者路线可能从未真正注册过并且测试匹配?

Screenshot of React output in Chrome Dev Tools

我在 ReportContainer 组件的渲染中放置了一个断点,但它从未到达它。

应用

import React from 'react'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import { connect } from 'react-redux'
import styles from './App.css'
import { logout } from '../actions/user'
import { userIsAuthenticatedRedir, userIsNotAuthenticatedRedir } from '../auth'

import ProtectedComponent from './App.jsx'
import LoginComponent from './Login.jsx'
import Home from './Home'

const Login = userIsNotAuthenticatedRedir(LoginComponent)
const Protected = userIsAuthenticatedRedir(ProtectedComponent)


function App({ user, logout }) {
  return (
    <Router>
      <div className={styles.wrapper}>
        <div className={styles.content}>
          <Route exact path="/" component={Home}/>
          <Route exact path="/login" component={Login}/>
          <Route exact path="/app" component={Protected}/>
        </div>
      </div>
    </Router>
  )
}

const mapStateToProps = state => ({
  user: state.user
})

export default connect(mapStateToProps, { logout })(App)

App.jsx

import React, { Component } from 'react';
import { connect } from 'react-redux'

import mainLayout from '../layouts/main';
import Report from './Report.jsx';

const routes = [
  {
    label: 'Reports',
    subs: {
      links: [
        {
          label: 'Report 1',
          link: '/app/reports/report1',
        }
      ],
      paths: [
        {
          path: '/app/reports/report1',
          component: Report
        }
      ]
    }
  }
];

export class AppContainer extends Component {

  render() {

    return (
        React.createElement(mainLayout, { routes })
    );
  }
}
export default connect(null, null)(AppContainer)

主要布局

我在这里对路由进行了硬编码,而不是从路由对象动态构建它,以防出现问题。

import React from 'react'
import { Route } from 'react-router-dom';

import AppMenuBar from '../components/AppMenuBar';
import Report from '../components/Report.jsx';

const MainForm = ({ routes }) => (
  <div>
      <AppMenuBar screen="app/main" routes={routes} />
      <div style={{ marginLeft: '250px' }}>
        <h1>Main Page</h1>
        <p> Default page for the /app location.</p>

        <Route 
          path='/app/reports/report1'
          key='r1'
          component={Report}
        />
      </div>
  </div>
)

export default MainForm

Screenshot of my rendered App component. This corresponds with the React dev tools output. Clicking on the Report 1 menu item yields this,也就是已更新 url,但屏幕是空白的。快速查看 React 输出显示根本没有渲染组件,只有来自 App.js.

的空路由

嵌套路由在这种情况下是否应该不起作用,我误解了它们应该如何工作? BrowserRouter 是否不知道嵌套路由,因此无法进行匹配,默认为空组件? None 我发现的示例跨越多个文件的嵌套路由(尽管它们显然使用多个组件)。想知道我的实现中是否缺少某些东西。

如果我应该参考这种模式的已知好例子,我将不胜感激指向正确方向的指针。谢谢!

从您的父路径中删除 exact

如果您将所有内容都写成内联,就很容易看出发生了什么:

<Route exact path="/foo" component={props => {
  // this component will only load if the url is *exactly* /foo
  // it doesn't matter if you have nested routes in here or not
  // because they will never be rendered if the url is not exactly /foo

  return <Route path="/foo/bar" component={FooBar} /> // <-- can't possibly work
}} />

比较一下:

<Route path="/foo" component={props => {
  // will always render if *containing* /foo (ie. /foo or /foo/bar)

  // now this nested path will at least be rendered when url is /foo/bar
  return <Route path="/foo/bar" component={FooBar} />
}} />