我知道指南中警告不要这样做,但我不确定我是否可以看到setState
从内部调用的问题componentWillUpdate
。确实,它可能会导致无限递归,除非您当然为该递归提供一个底部(一种打破它的方法)。例如,一种方法可能是检查第二个 ( nextState
) 参数,如果满足某些条件(即递归结束时),则componentWillUpdate
不再调用setState
。
作为一个最小的例子,想象一个完全没有属性的组件,只有两个状态。进一步想象第二个状态是从第一个状态异步获取的。例如,第一部分状态可以是提供给 Ajax 调用的某个参数,而第二部分状态是该调用的结果。所以基本上你调用this.setState
来配置参数,然后在里面componentWillUpdate
你可以做如下的事情(为了简单起见,我使用 awindow.setTimeout
作为 Ajax 调用的占位符):
const ComponentWithAsyncState = React.createClass({
getInitialState: function() {
return {
ajaxParams: '',
ajaxResult: ''
};
},
setAjaxParams: function(params) {
this.setState({ajaxParams: params});
},
componentWillUpdate: function(_, nextState) {
if (nextState.ajaxParams!=this.state.ajaxParams)
window.setTimeout(function imagineThisIsAjax() {
this.setState({ajaxResult: `result from ${nextState.ajaxParams}`});
}.bind(this), 2000);
},
当(例如通过此组件管理的某些控件)发生ajaxParams
更改时,操作序列将类似于(其中~~>
表示异步性):
setAjaxParams --> this.setState --> componentWillUpdate ~~> imagineThisIsAjax --> this.setState --> componentWillUpdate
即第二次调用componentWillUpdate
不会导致进一步this.setState
,因此递归将在那里结束。