调用的setState在渲染是不可以避免的 [英] Calling setState in render is not avoidable
问题描述
阵营文件指出,在渲染
函数应 纯粹的这意味着它不应该使用 this.setState
在里面。但是,我相信,当国家决定于远程,即从阿贾克斯独特叫声唯一的解决办法的结果是的setState()
在渲染
函数
React document states that the render
function should be pure which mean it should not use this.setState
in it .However, I believe when the state is depended on 'remote' i.e. result from ajax call.The only solution is setState()
inside a render
function
在我case.Our用户应该能够登录。登录后,我们还需要检查用户的访问(Ajax调用)来决定如何显示PAGE电泳code是像这样
In my case.Our users can should be able to log in. After login, We also need check the user's access (ajax call )to decide how to display the page.The code is something like this
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
,因为当用户点击登录按钮,该网页重新渲染,并且还需要Ajax调用code>的setState 里面的渲染
功能,违反原则做出反应。
The ajax call can not appear in componentDidMount
because when user click LOGIN button the page is re-rendered and also need ajax call .So I suppose the only place to setState
is inside the render
function which breach the React principle
没有更好的办法?在此先感谢
Any better solutions ? Thanks in advance
推荐答案
渲染
应的总是的保持纯洁。这是一个非常不好的做法,做到边effecty的东西在里面,并调用的setState
是一个大红旗;在这样一个简单的例子就可以工作了好了,但它的道路,高度不可维护的部件,再加上它只能是因为副作用是异步。
render
should always remain pure. It's a very bad practice to do side-effecty things in there, and calling setState
is a big red flag; in a simple example like this it can work out okay, but it's the road to highly unmaintainable components, plus it only works because the side effect is async.
相反,想想各种状态的组件可以在 - 就像你在模拟一个状态机(事实证明这,你是):
Instead, think about the various states your component can be in — like you were modeling a state machine (which, it turns out, you are):
- 初始状态(用户没有点击按钮)
- 待授权(用户点击登录,但我们不知道的Ajax请求的结果还)
- 用户有权访问的东西(我们已经拿到了Ajax请求的结果)
与组件的状态模型了这一点,你是好去。
Model this out with your component's state and you're good to go.
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 />;
}
}
});
这篇关于调用的setState在渲染是不可以避免的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!