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} />
}} />
我是 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} />
}} />