如果我不应该在 componentWillUpdate 中调用 setState,我该如何更新状态(使用 ReactJS)?
How do I update the state (using ReactJS) if I should not call setState in componentWillUpdate?
当我在 componentWillUpdate
中 setState
时,componentWillUpdate
运行在无限循环中,不会停止被触发。
这永远不会让我的 render
有机会反映我的更改。如果我不应该使用 componentWillUpdate
,我该如何更改状态?
编辑:我已经有了一些理解,不应该在 componentWillUpdate 中调用 setState
。我只是很困惑我应该做什么作为替代方案。
编辑 #2:我从 componentWillReceiveProps
开始,但当我的 Parent 组件改变状态时,我似乎无法触发此功能。我将 parent 中的状态作为道具提供给我的 child。
首先要做的是查看此方法的官方文档 (link)。当函数实际被调用时,您可以在哪里阅读。
然后阅读常见错误(注):
You cannot use this.setState() in this method. If you need to update state in response to a prop change, use componentWillReceiveProps instead.
你改变状态,React 自动调用 componentWillUpdate
。
我知道 guide 中警告不要这样做,但我不确定我是否能看到从 componentWillUpdate
中调用 setState
的问题。诚然,它可能会导致无限递归 除非 当然,您为该递归提供了一个底部(一种突破它的方法)。例如。一种方法是检查 componentWillUpdate
中的第二个 (nextState
) 参数,如果满足某些条件(即递归结束时)则不再调用 setState
。
作为一个最小的例子,假设一个组件根本没有任何属性,只有两个状态。进一步想象,第二个状态是从第一个异步获取的。例如。第一个状态可以是提供给 Ajax 调用的一些参数,第二个状态是该调用的结果。所以基本上你调用 this.setState
来配置参数,然后在 componentWillUpdate
里面你可以做类似下面的事情(为了简单起见,我使用 window.setTimeout
作为 [=35= 的占位符] 调用):
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
,因此递归将在那里结束。
当我在 componentWillUpdate
中 setState
时,componentWillUpdate
运行在无限循环中,不会停止被触发。
这永远不会让我的 render
有机会反映我的更改。如果我不应该使用 componentWillUpdate
,我该如何更改状态?
编辑:我已经有了一些理解,不应该在 componentWillUpdate 中调用 setState
。我只是很困惑我应该做什么作为替代方案。
编辑 #2:我从 componentWillReceiveProps
开始,但当我的 Parent 组件改变状态时,我似乎无法触发此功能。我将 parent 中的状态作为道具提供给我的 child。
首先要做的是查看此方法的官方文档 (link)。当函数实际被调用时,您可以在哪里阅读。
然后阅读常见错误(注):
You cannot use this.setState() in this method. If you need to update state in response to a prop change, use componentWillReceiveProps instead.
你改变状态,React 自动调用 componentWillUpdate
。
我知道 guide 中警告不要这样做,但我不确定我是否能看到从 componentWillUpdate
中调用 setState
的问题。诚然,它可能会导致无限递归 除非 当然,您为该递归提供了一个底部(一种突破它的方法)。例如。一种方法是检查 componentWillUpdate
中的第二个 (nextState
) 参数,如果满足某些条件(即递归结束时)则不再调用 setState
。
作为一个最小的例子,假设一个组件根本没有任何属性,只有两个状态。进一步想象,第二个状态是从第一个异步获取的。例如。第一个状态可以是提供给 Ajax 调用的一些参数,第二个状态是该调用的结果。所以基本上你调用 this.setState
来配置参数,然后在 componentWillUpdate
里面你可以做类似下面的事情(为了简单起见,我使用 window.setTimeout
作为 [=35= 的占位符] 调用):
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
,因此递归将在那里结束。