【问题标题】:React: Authentification and avoiding repeating code componentsReact:身份验证和避免重复代码组件
【发布时间】:2017-06-28 01:46:28
【问题描述】:

我所有的主要反应组件都有这样的部分:

export default class ExampleMain extends Component {
    constructor(props) {
        super(props)
        this.state = {
            isAuthenticated: Meteor.userId() !== null
        }
    }

    componentWillMount() {
        if (!this.state.isAuthenticated) browserHistory.push('/login')
    }
    componentDidUpdate() {
        if (!this.state.isAuthenticated) browserHistory.push('/login')
    }
}

我正在检查用户是否登录。如果这是错误的,用户将被重定向到登录路径。 由于这部分用于许多组件,我在想是否可以优化它以获得 DRY 代码...

更新

我正在使用反应路由器:

render((
    <Router history={ browserHistory }>
        <Route path='/' component={ App }>
            <IndexRoute component={ Main } />
            <Route path='login' component={ Login } />
            <Route path='content/:id' component={ Content } />
        </Route>
        <Redirect from='*' to='/' />
    </Router>
), document.getElementById('root'))

【问题讨论】:

  • 你在使用 Redux/React-Router 吗?
  • 我正在使用 react 路由器
  • 您可以在组件的构造函数中检查一次,该组件位于 Route 中,它是所有这些组件的父级。
  • 我已经更新了问题以向您展示我的路由示例...所以您的意思是检查App 组件,对吗?
  • 是的。您也可以使用 onEnter 挂钩,甚至在渲染 App 组件之前进行该逻辑和重定向。但是由于 login 路由是嵌套的,除非您更改路由顺序,否则钩子不会对您有太大帮助。 (因为无论如何都必须渲染 App,所以您可能希望登录在外面)

标签: javascript reactjs


【解决方案1】:

你可以试试这样的:

<Router history={ browserHistory }>
    <Route path='/' component={ App }>
        <IndexRoute component={ Main } />
        <Route path='/login' component={ Login } />
        <Route path='content/:id' component={ Content } />
    </Route>
    <Redirect from='*' to='/' />
</Router>

在 App 中,使用 withRouter 在组件内“注入”路由器:

import { withRouter } from 'react-router';

class App extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            isAuthenticated: Meteor.userId() !== null
        }
    }

    componentWillMount() {
        if (!this.state.isAuthenticated) {
           this.props.router.push('/login');
        }
    }
}

export default withRouter(App);

【讨论】:

  • 只是问...应用程序是我的主要组件,它为我提供了包装主布局。这始终是相同的(导航栏、背景图像等)。也在登录页面。所以我想我必须渲染App 并对所有其他组件进行身份验证......
  • 您最了解您的应用程序的需求,然后忽略我的登录路线建议并将其重新嵌套在应用程序中。我会编辑。
  • 接近工作...但是如果用户退出我会收到错误Warning: setState(...): Cannot update during an existing state transition
  • @user3142695 这最终解决了还是您仍然收到该错误?
  • 您可以尝试将if (isAutheniticated 块移动到componentWillMount 而不是构造函数吗?
【解决方案2】:

也许this 可以帮助你。我会尝试在路由之前使用任何钩子。但是你总是可以用that example这样的功能扩展你自己的类

function requireAuth(nextState, replace) {
  if (!auth.loggedIn()) {
    replace({
      pathname: '/login',
      state: { nextPathname: nextState.location.pathname }
    })
  }
}

render((
  <Router history={ browserHistory }>
    <Route path='/' component={ App }>
      <IndexRoute component={ Main } />
      <Route path='login' component={ Login } />
      <Route path='content/:id' component={ Content } onEnter={requireAuth} />
    </Route>
    <Redirect from='*' to='/' />
  </Router>
), document.getElementById('root'))

要查看完整代码,请点击上面的链接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-10
    • 2020-04-10
    • 1970-01-01
    • 2021-03-16
    • 2021-10-04
    • 2013-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多