我正在撰写一个非常简单的应用来学习react-router
。
当客户想要访问某个页面(products
,about
,home
)并且未登录时,会将其重定向到登录页面,登录后,它被重定向回到它想要访问的同一页面。
这是路由器的定义:
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
时(在transition
或response
上)onAbort
在服务器端调用,这会导致无限循环发生在服务器端崩溃。因为onAbort
函数中存在另一个重定向,导致onAbort
被一次又一次地调用。
我该如何解决这个问题?我onAbort
中有什么东西可以丢失吗?
代码的Bitbucket存储库(虽然它不起作用,因为我从其他地方复制了它,因此没有设置环境): https://bitbucket.org/arianhosseinzadeh/react-router-poc
更新
事实证明问题的根源在于路线的定义:
var routes =( );
正如您在About.js中看到的那样,如果客户端未登录,则会将其重定向到登录状态。 (包括家庭在内的其他组件也是如此)
home是DefaultRoot,因此当客户端想要浏览/(未登录)时,它将被路由到home组件。它将被重定向到登录,令人惊讶的是AGAIN渲染回家并且它会陷入无限循环。
如果你好奇为什么会这样,请参考这个问题:
即使它不应该
,也会对DefaultRoute的转换进行操作