在onAbort

时间:2015-09-02 05:45:55

标签: javascript reactjs react-router

我正在撰写一个非常简单的应用来学习react-router。 当客户想要访问某个页面(productsabouthome)并且未登录时,会将其重定向到登录页面,登录后,它被重定向回到它想要访问的同一页面。

这是路由器的定义:

var router = function(req, res, next) {
    var router = Router.create({
        routes: routes,
        onAbort: function(abortReason) {
            var url = router.makePath(abortReason.to, abortReason.params, abortReason.query);
            res.redirect(url);
        }
    });
    router.run(function(Handler, state) {
        var initialState = {};
        var markup = React.renderToString(<Handler {...initialState}/>);
        res.render('react-app', {
            markup: markup,
            state: JSON.stringify(initialState)
        });
    });
};

路线:

var routes = (
    <Route name="app" path="/" handler={App}>
        <Route path="about" name="about" handler={About} />
        <Route path="products" name="products" handler={Products} />
        <Route path="login" name="login" handler={Login} />
        <DefaultRoute name="home" handler={Home} />
    </Route>
);

About.js(用户必须登录才能访问的页面):

'use strict';

    var React = require('react');
var loginStore = require('../stores/LoginStore');
var About = React.createClass({
    displayName: 'About',
    statics: {
        willTransitionTo(transition) {
            if (!loginStore.isLoggedIn()) {
                loginStore.setTransitionPath(transition.path);
                transition.redirect('login');
            }
        }
    },
    _getLoginState() {
        return {
            userLoggedIn: loginStore.isLoggedIn()
        };
    },
    componentDidMount() {
        this.changeListener = this._onChange;
        loginStore.addChangeListener(this.changeListener);
    },
    _onChange() {
        this.setState(this._getLoginState());
    },
    getInitialState() {
        return {
            userLoggedIn: this._getLoginState()
        };
    },
    componentWillUnmount: function() {
        loginStore.removeChangeListener(this.changeListener);
    },
    getDefaultProps: function() {
        return {
            message: 'Default Prop for About page'
        };
    },
    render: function() {
        return (<div>
        {this.props.message}
        </div>);
    }
});

module.exports = About;

Login.js(登录页面):

'use strict';

    var React = require('react');
    var AuthenticationServices = require('../Services/AuthenticationService');
    var Login = React.createClass({

        displayName: 'Login',

        propTypes: {},

        getDefaultProps: function() {
            return {
                message: 'Default Prop for Login page'
            };
        },
        _login: function(e) {
            e.preventDefault();
            AuthenticationServices.login('arian', '1111');
        },
        _logout: function() {
            e.preventDefault();
            AuthenticationServices.logout();
        },
        render: function() {
            return (<div>
                <button type="button" onClick={this._login}>Log in</button>
                <button type="button" onClick={this._logout}>Log out</button>
            </div>);
        }
    });

    module.exports = Login;

根据我的理解,调用redirect时(在transitionresponse上)onAbort在服务器端调用,这会导致无限循环发生在服务器端崩溃。因为onAbort函数中存在另一个重定向,导致onAbort被一次又一次地调用。

我该如何解决这个问题?我onAbort中有什么东西可以丢失吗?

代码的Bitbucket存储库(虽然它不起作用,因为我从其他地方复制了它,因此没有设置环境): https://bitbucket.org/arianhosseinzadeh/react-router-poc

更新

事实证明问题的根源在于路线的定义:

var routes =(                                               );

正如您在About.js中看到的那样,如果客户端未登录,则会将其重定向到登录状态。 (包括家庭在内的其他组件也是如此)

home是DefaultRoot,因此当客户端想要浏览/(未登录)时,它将被路由到home组件。它将被重定向到登录,令人惊讶的是AGAIN渲染回家并且它会陷入无限循环。

如果你好奇为什么会这样,请参考这个问题:

即使它不应该

,也会对DefaultRoute的转换进行操作

0 个答案:

没有答案