簡體   English   中英

當登錄狀態處於組件狀態時,如何使用 react-router 實現與登錄相關的路徑?

[英]How to implement login-dependent paths with react-router, when the login-status is in the component-state?

我正在嘗試從react-router -repo 實現auth-flow 示例,但是我遇到了用例的問題,我不喜歡 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
}

由於我只想在登錄時查看我的組件,我嘗試根據login ()onEnter={requireAuth}更改我的路由中的路徑:

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() 不起作用,因為它不是公共函數。 根據這個答案,ReactJS 中的公共函數無法訪問內部狀態,正如 React 架構所預期的那樣,因此用static實現它無濟於事。

我可能會繼續將登錄狀態保存在本地存儲中,但我想知道在 ReactJS 中是否有不同的方法來解決這個問題。

我在 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;

效果很好,用這個構建了幾個應用程序:)

用戶商店.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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM