首页 文章

当login-status处于组件状态时,如何使用react-router实现与登录相关的路径?

提问于
浏览
2

我正试图从react-router -repo实现auth-flow example,但我作为一个ReactJS初学者 .

我的登录状态是基于CSRF-cookie的存在,所以我的应用程序中有一个方法可以检索CSRF-cookie并将其值保存在以下状态:

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

    this.state = {
      csrfToken : '',
      log : {}
    }
  }

setCSRFToken() {
  this.state = { csrfToken : cookie.load('csrf') };
  this.setState({ csrfToken : this.state.csrfToken });
}

loggedIn() {
  return !!this.state.csrfToken
}

因为我只想在登录时查看我的组件,所以我尝试根据使用onEnter = 的loggedIn()更改路径中的路径:

function requireAuth(nextState, replace) {
  if (!App.loggedIn()) {
    console.log('No csrfToken found, asking for login')
    replace({
      pathname: '/login',
      state: {nextPathname: nextState.location.pathname }
    })
  }
}

render((
  <Router history={hashHistory}>
    <Route path="/" component={App} onEnter={requireAuth}>
      <IndexRoute component={Home}/>
      <Route path="/hello" component={Hello}/>
    </Route>
  </Router>

), document.querySelector('#main'))

App.loggedIn()虽然不起作用,因为它不是公共函数 . 根据这个answer,ReactJS中的公共函数无法访问内部状态,正如React的体系结构所预期的那样,因此使用static实现它无济于事 .

我可以继续将登录状态保存在本地存储中,但我想知道在ReactJS中是否有不同的方法来解决这个问题 .

1 回答

  • 1

    我在Store中设置登录状态(如Flux建议)和路线:

    const UserStore = require("./stores/UserStore.js");
    
    let is_user_logged_in = !!UserStore.getToken();
    
    UserStore.addChangeListener(() => {
        is_user_logged_in = !!UserStore.getToken();
    });
    
    function requireAuth(nextState, replaceState) {
        if (!is_user_logged_in) {
            replaceState({nextPathname: 'login'}, '');
        }
    }
    
    const routes = (
        <Route path="/" component={Layout}>
            <IndexRoute component={Home}/>
            <Route path="login" component={Login}/>
            <Route path="secret" component={Secret} onEnter={requireAuth}/>
            <Route path="*" component={NotFound}/>
        </Route>
    );
    
    module.exports = routes;
    

    效果很好,用这个构建了几个应用程序:)

    UserStore.js:

    "use strict";
    const AppDispatcher = require('./../dispatchers/AppDispatcher.js');
    const EventEmitter = require('eventemitter3');
    const assign = require('object-assign');
    const store = require('store');
    const Api = require('./../helpers/Api.js');
    const UserActions = require('./../actions/UserActions.js');
    import { browserHistory } from 'react-router';
    
    const UserStore = assign({}, EventEmitter.prototype, {
    
        token: null,
        error: null,
    
        setError: function ({error}) {
            this.error = error;
        },
    
        getError: function () {
            return this.error;
        },
    
        setToken: function ({token}) {
            this.token = token;
    
            if (token !== null) {
                store.set('token', token);
            } else {
                store.remove('token');
            }
        },
    
        getToken: function () {
            return this.token;
        },
    
        emitChange: function () {
            this.emit('USER_CHANGE');
        },
    
        addChangeListener: function (cb) {
            this.on('USER_CHANGE', cb);
        },
    
        removeChangeListener: function (cb) {
            this.removeListener('USER_CHANGE', cb);
        },
    
    });
    
    AppDispatcher.register(function (action) {
    
        switch (action.actionType) {
            case 'user_login':
                Api.login({
                    username: action.data.username,
                    password: action.data.password,
                    cb: function ({error, response}) {
                        if (error !== null) {
                            console.log('#dfd4sf424');
                            console.log(error);
                            UserActions.logout();
                        } else {
                            if (response['success'] === false) {
                                UserStore.setError({error: response['error']});
                                UserStore.emitChange();
                            } else {
                                UserStore.setError({error: null});
                                UserStore.setToken({token: response['auth-token']});
                                UserStore.emitChange();
                            }
                        }
                    }
                });
                break;
            case 'user_logout':
                UserStore.setToken({token: null});
                UserStore.setError({error: null});
                UserStore.emitChange();
                break;
            case 'user_auto_login':
                UserStore.setToken({token: action.data.token});
                UserStore.setError({error: null});
                UserStore.emitChange();
                break;
        }
    });
    
    module.exports = UserStore;
    

相关问题