如果我不应该在 componentWillUpdate 中调用 setState,我该如何更新状态(使用 ReactJS)?

How do I update the state (using ReactJS) if I should not call setState in componentWillUpdate?

当我在 componentWillUpdatesetState 时,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,因此递归将在那里结束。