在promise中使用setState后,React不会重新渲染

时间:2014-11-05 15:26:48

标签: javascript reactjs

每次更改道具时,组件都会调用onTermChange并获取此组件的详细信息,并带有返回对象数组的promise。

问题是,当调用setState时,没有任何反应,并且不会使用新的细节重新呈现组件。

module.exports = React.createClass({
displayName: 'TaxonomySelect',

getInitialState: function () {
    return {
        children: undefined
    };
},

componentDidMount: function () {
    this.onTermChange(this.props.term);
},

componentWillReceiveProps: function (nextProps) {
    this.props.term = this.props.term || null;

    if (this.props.term) {
        this.onTermChange(nextProps.term.id);
    } else {
        this.onTermChange(nextProps.term);
    }
},

onTermChange: function (term) {
    this.setState({children: undefined});

    TaxonomyStore.getTerm(this.props.term)
        .bind(this)
        .then(function (term) {
            TaxonomyStore.merge(9999,{
                    description: 'No specific topic',
                    id: 9999
            });
            if (term.path && term.path.length === 3) {
                term.children.unshift(TaxonomyStore.get(9999));
            }

            console.log(term.id, term.children);

            this.setState({children: term.children});
            this.forceUpdate();
            this.render();
        });
},

onSelect: function (id) {
    if (this.props.onChange) {
        this.props.onChange(TaxonomyStore.get(id));
    }
},

render: function () {
    if (!Array.isArray(this.state.children) || this.state.children.length < 1) {
        return null;
    };

    var options = this.state.children.map(function (term) {
        return {
            value: term.id.toString(),
            label: term.description
        };
    });

    var value = this.props.value && this.props.value.toString();

    return (
        <div>
            <Select name={this.props.name} value={value} options={options} onChange={this.onSelect} />
        </div>
    );
}
});

3 个答案:

答案 0 :(得分:2)

当您致电this.setState({children: term.children}); this时,等于其定义的功能,而不是反应组件。

可能发生异常,但您的承诺不会调用.error来捕获并记录它。

答案 1 :(得分:1)

如果您致电this.forceUpdate(),则无需致电this.setState。此外,您永远不应该调用组件的render方法。

很难说它为什么不重新渲染,但我会发表一些debugger语句,看看render是否被调用。我猜这总是在this.onTermChange中调用componentWillReceiveProps可能是一个潜在的问题。

答案 2 :(得分:0)

我遇到同样的问题,受到@ z5h的启发,我使用本地viraible来引用this之外的Promise,它有效!

在你的情况下:

onTermChange: function (term) {
    this.setState({children: undefined});

    let _this = this; // change
    TaxonomyStore.getTerm(this.props.term)
        .bind(this)
        .then(function (term) {
            TaxonomyStore.merge(9999,{
                    description: 'No specific topic',
                    id: 9999
            });
            if (term.path && term.path.length === 3) {
                term.children.unshift(TaxonomyStore.get(9999));
            }

            console.log(term.id, term.children);

            _this.setState({children: term.children}); //change

        });
}

有关thisjs的更多信息:How does the “this” keyword work?