在render中调用setState是不可避免的
React文档指出render
函数应该是
函数,这意味着它不应该在函数中使用this.setState
。但是,我相信当状态依赖于“远程”(即由ajax调用产生的结果)时。唯一的解决方案是setState()
在render
函数内部
就我而言。我们的用户应该可以登录。登录后,我们还需要检查用户的访问权限(ajax调用),以决定如何显示页面。代码是这样的
React.createClass({ render:function(){
if(this.state.user.login)
{
//do not call it twice
if(this.state.callAjax)
{
var self=this
$.ajax{
success:function(result)
{
if(result==a)
{self.setState({callAjax:false,hasAccess:a})}
if(result==b)
{self.setState({callAjax:false,hasAccess:b})}
}
}
}
if(this.state.hasAccess==a) return <Page />
else if(this.state.hasAccess==a) return <AnotherPage />
else return <LoadingPage />
}
else
{
return <div>
<button onClick:{
function(){this.setState({user.login:true})}
}>
LOGIN
</button>
</div>
}
}
})
之所以无法显示ajax调用,componentDidMount
是因为当用户单击LOGIN按钮时,页面会重新呈现,并且还需要ajax调用。因此,我想唯一的位置setState
就是render
违反React原理的函数
内
有更好的解决方案吗?提前致谢
回答:
render
应 始终
保持纯净。在那儿做副作用的东西是非常不好的做法,打电话setState
是一个很大的危险信号。在这样的简单示例中,它可以解决问题,但是这是高度不可维护的组件之路,而且它只能起作用,因为副作用是异步的。
相反,请考虑您的组件可能处于的各种状态-就像您在建模状态机一样(事实证明,您是):
- 初始状态(用户尚未单击按钮)
- 等待授权(用户单击登录名,但我们尚不知道Ajax请求的结果)
- 用户有权访问某些内容(我们已经获得了Ajax请求的结果)
使用组件的状态对此建模,您很高兴。
React.createClass({ getInitialState: function() {
return {
busy: false, // waiting for the ajax request
hasAccess: null, // what the user has access to
/**
* Our three states are modeled with this data:
*
* Pending: busy === true
* Has Access: hasAccess !== null
* Initial/Default: busy === false, hasAccess === null
*/
};
},
handleButtonClick: function() {
if (this.state.busy) return;
this.setState({ busy: true }); // we're waiting for ajax now
this._checkAuthorization();
},
_checkAuthorization: function() {
$.ajax({
// ...,
success: this._handleAjaxResult
});
},
_handleAjaxResult: function(result) {
if(result === a) {
this.setState({ hasAccess: a })
} else if(result ===b ) {
this.setState({ hasAccess: b })
}
},
render: function() {
// handle each of our possible states
if (this.state.busy) { // the pending state
return <LoadingPage />;
} else if (this.state.hasAccess) { // has access to something
return this._getPage(this.state.hasAccess);
} else {
return <button onClick={this.handleButtonClick}>LOGIN</button>;
}
},
_getPage: function(access) {
switch (access) {
case a:
return <Page />;
case b:
return <AnotherPage />;
default:
return <SomeDefaultPage />;
}
}
});
以上是 在render中调用setState是不可避免的 的全部内容, 来源链接: utcz.com/qa/430419.html