React 路由器 v4 路由设置

React router v4 routes setup

在从 v2 迁移到 v4 的过程中,我的路由现在设置如下:

ReactDOM.render(
<Provider store={store}>
    <Router>
        <Route path='/admin' component={App} />
    </Router>
</Provider>
, document.getElementById('root'))

应用组件是

class App extends Component {

  render() {
    return (
      <AppContainer>
        <Switch>
          <Route path="/admin/dashboard" component={Dashboard} />
          <Route path="/admin/signin" component={SignIn} />
          <Route path="/admin/settings" component={Settings} />
        </Switch>
      </AppContainer>
    );
  }
}

在应用程序容器中,它会调用一个检查登录的操作,然后 router.history.push('/admin/dashboard') 如果登录有效。 AppContainer 组件的其余部分是

render() {
    return (
        <div>
          {this.props.children}
          <Detached />
        </div>
    )
  }

转到 /admin 会将您正确地转到 /admin/dashboard。 转到 /admin/dashboard 404,似乎甚至不匹配第一个路由路径“/admin”。

我做错了什么吗?去 /admin/xxxxx 不应该被第一条路线匹配吗?

了解您的 404 路由在哪里以及是否有任何逻辑控制对“/admin/dashboard”的推送会很有帮助。

只要没有 'strict' 或 'exact' prop.

'/admin/xxxxx' 肯定会匹配 '/admin'

潜在错误:如果 AppContainer 中的逻辑检查登录状态并执行推送到“/admin/dashboard”而不考虑当前路径名,那么您的应用可能会陷入以下递归循环:

  1. 用户导航到“/admin”
  2. 路由根据路径属性“/admin”检查路径名“/admin”并找到匹配项
  3. 路由渲染 'App' 组件
  4. AppContainer 验证用户是否已登录
  5. AppContainer 将用户推送到“/admin/dashboard”
  6. 应用程序重新呈现路径名“/admin/dashboard”
  7. 路由根据路径属性“/admin”检查路径名“/admin/dashboard”并找到匹配项
  8. 路由渲染App组件
  9. AppContainer 验证用户是否已登录
  10. AppContainer 将用户推送到“/admin/dashboard”
  11. 应用程序重新呈现路径名“/admin/dashboard”
  12. ...

最简单的解决方法是仅在路径名为“/admin”时推送到“/admin/dashboard”。

可以说认知开销较少的修复方法是将手册 history.push 删除为“/admin/dashboard”并将 App 更改为以下内容:

class App extends Component {

    render() {
        return (
            <AppContainer>
                <Switch>
                    <Route exact path="/admin" render={() => <Redirect to='/admin/dashboard' />} />
                    <Route path="/admin/dashboard" component={Dashboard} />
                    <Route path="/admin/signin" component={SignIn} />
                    <Route path="/admin/settings" component={Settings} />
                </Switch>
            </AppContainer>
        );
    }
}