当我setState
componentWillUpdate
时,componentWillUpdate
在无限循环中运行,并且不会被触发。
这永远不会让render
有机会反映我的变化。如果我不使用componentWillUpdate
?
编辑:我已经了解不应在componentWillUpdate中调用setState
。我只是把我应该做的事情搞糊涂了。
编辑#2:我从componentWillReceiveProps
开始,但是当我的父组件改变状态时,我似乎无法触发此功能。我从父母那里提供这种状态作为我孩子的道具。
答案 0 :(得分:31)
首先要检查此方法的官方文档(link)。在实际调用函数时可以读取的位置。
然后阅读常见错误(注意):
您不能在此方法中使用this.setState()。如果您需要更新状态以响应prop更改,请改用componentWillReceiveProps。
您更改状态,React会自动调用componentWillUpdate
。
答案 1 :(得分:-1)
我理解在guide中提醒我这一点,但我不确定从setState
内调用componentWillUpdate
是否可以看到问题。没错,它可能会导致无限递归,除非当然你为这种递归提供了一个底线(一种突破它的方法)。例如。一种方法可能是检查nextState
中的第二个(componentWillUpdate
)参数,如果满足某些条件(即递归结束时),则不再调用setState
。
作为一个最小的例子,想象一下根本没有属性的组件,只有两个状态。进一步想象第二段状态是从第一段异步获得的。例如。第一个状态可以是一个提供给Ajax调用的参数,第二个状态是该调用的结果。所以基本上你调用this.setState
来配置参数然后在componentWillUpdate
里面你可以做类似下面的事情(为了简单起见我使用window.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
,因此递归将在那里结束。