如何使用 reactjs、redux 和 redux-simple-router 根据身份验证状态共享 root URL?

How to share the root URL according to the auth status using reactjs, redux and redux-simple-router?

我正在构建一个基于 reactjs、redux 和 react-router (redux-simple-router) 的网站,但我有点卡在弄清楚如何根据用户是否已通过身份验证来共享根路径与否。

我正在查看这个示例 https://github.com/reactjs/react-router/tree/master/examples/auth-with-shared-root,但老实说我无法让它工作。

我有两种不同的布局。第一个是 public 布局,当用户未通过身份验证时显示。从这里您可以访问登录页面和注册。

用户通过身份验证后,我想向他展示内部应用程序,这是一个完全不同的布局,但在同一根目录下进行URL。

例如: http://example.com/

当用户未通过身份验证时:

<Route path='/' name='homepage' component={SiteLayout}>
  <IndexRoute component={HomeView} />
  <Route path='/login' name='login' component={LoginView} />
  <Route path='/join' name='join' component={RegistrationView} />
  <Route path='/404' component={NotFoundView} />
  <Redirect from='*' to='/404' />
</Route>

并且认证后,保持同根URL。

<Route path='/' name='feeds' component={InternalLayout}>
  <IndexRoute component={FeedsView} />
  <Route path='/profile' name='login' component={ProfileView} />
  <Route path='/settings' name='join' component={SettingsView} />
  <Route path='/search' name='join' component={SearchView} />
</Route>

就像 Facebook 一样。

我的问题是(如果你能提供一个例子那就太好了):如何根据身份验证状态在相同的 URL 下呈现不同的布局?

PD:我有一个令牌 class,我在其中存储身份验证状态 (JWT),方法是 hasToken。

在示例中我使用的是 JSX 语法,我不知道是否必须切换到配置语法才能达到预期的结果。

感谢任何帮助。

您可以创建一个新组件,如果用户未登录则显示 HomeView,如果用户已通过身份验证则显示 FeedsView。

所以你有:

<IndexRoute component={RootComponent} />

RootComponent 应该做类似的事情:

render() {
  ...
  var child = (hasToken)?FeedsView:HomeView
  return (
    <div>
      {child}
    </div>
  )
}

解决这个问题的一种方法是使用对象文字形式。您需要创建一个额外的组件来包含您的根路由。它不需要任何花哨的东西,

<div>{this.props.children}</div>

会做(例如应用程序),然后路线可能如下所示:

const redirectToLogin = (nextState, replace) => {
  if (isLoggedIn()) {
    replace('/login')
  }
}

const routes = {
    component: App,
    childRoutes: [
    {
        path: '/',
        getComponent(location, cb) {
            return isLoggedIn() ? cb(null, InternalLayout) : cb(null, SiteLayout);
        },
        indexRoute: { 
            getComponent: (location, cb) => {
                return isLoggedIn() ? cb(null, FeedsView) : cb(null, HomeView);
            }
        },
        childRoutes: [
            // Your not authenticated views under SiteLayout
            { path: '/login', component: 'LoginView'},
            { path: '/join', component: 'RegistrationView'},
            // etc.
            {
                // if not logged in, redirect to login page, once the user logs in, they'll be redirected to the childroute 
                onEnter: redirectToLogin,
                childRoutes: [
                    // Your authenticated views under FreedsView
                    { path: '/profile', component: 'ProfileView'},
                    { path: '/settings', component: 'SettingsView' },
                    // etc.
                ]
            }
        ]
    }
    ]
}

希望对您有所帮助。