【问题标题】:How to share the root URL according to the auth status using reactjs, redux and redux-simple-router?如何使用 reactjs、redux 和 redux-simple-router 根据 auth 状态共享根 URL?
【发布时间】:2016-05-23 02:52:40
【问题描述】:

我正在构建一个基于 reactjs、redux 和 react-router (redux-simple-router) 的网站,但我有点纠结于如何根据用户是否经过身份验证来共享根路径.

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

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

用户通过身份验证后,我想向他展示内部应用程序,这是一个完全不同的布局,但在同一个根 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:我有一个 Token 类,我在其中存储身份验证状态 (JWT),并带有一个方法 hasToken。

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

感谢任何帮助。

【问题讨论】:

    标签: reactjs react-router redux react-router-redux


    【解决方案1】:

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

    <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.
                    ]
                }
            ]
        }
        ]
    }
    

    我希望这会有所帮助。

    【讨论】:

    • 谢谢。这正是我想要的。
    【解决方案2】:

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

    所以你有:

    <IndexRoute component={RootComponent} />
    

    并且 RootComponent 应该执行以下操作:

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

    【讨论】:

    • 感谢您的回答。这解决了我的部分问题。因为我不仅想从 HomeView 切换到 FeedsView,还想在一组路线之间切换。就像我在描述中发布的那样:我想启用一组路由,其布局取决于身份验证状态。有了你的回答,我可以在布局之间切换,但我仍然需要控制内部组件。匿名用户无法访问“/profile”、“/settings”或“/search”路由。
    • 您可以在 ComponentWillMount 中检查身份验证状态,并在需要时重定向到登录。 componentWillMount() { if (!hasToken){ this.props.history.push('/login'); } }
    猜你喜欢
    • 2018-08-23
    • 2016-01-17
    • 2019-12-10
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 2020-08-04
    • 2020-12-10
    相关资源
    最近更新 更多