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

时间:2015-03-09 14:58:04

标签: javascript reactjs

当我setState componentWillUpdate时,componentWillUpdate在无限循环中运行,并且不会被触发。

这永远不会让render有机会反映我的变化。如果我不使用componentWillUpdate

,如何更改状态?

编辑:我已经了解不应在componentWillUpdate中调用setState。我只是把我应该做的事情搞糊涂了。

编辑#2:我从componentWillReceiveProps开始,但是当我的父组件改变状态时,我似乎无法触发此功能。我从父母那里提供这种状态作为我孩子的道具。

2 个答案:

答案 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,因此递归将在那里结束。