在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

回到顶部