选择性地反应不将新道具传递给渲染对象

时间:2015-02-25 00:21:44

标签: javascript reactjs

我正在处理多阶段表单,该表单通过基于this guide的AJAX获取一些中间数据。我有一个奇怪的问题,React并没有将新道具传递给组件。

// MyForm.js.jsx
var MyForm = React.createClass({
    render: function() {
        switch(this.state.stage) {
            case 1:
                return <InitialFields 
                            nextStage={this.nextStage}
                            save={this.save}
                        />
            case 2:
                return <ChoiceFields 
                            title="Choose first thing:"
                            field="first_id"
                            options={this.state.firstChoices}
                            nextStage={this.nextStage}
                            save={this.save}
                        />
            case 3:
                return <ChoiceFields 
                            title="Choose second thing:"
                            field="second_id"
                            options={this.state.secondChoices}
                            nextStage={this.nextStage}
                            save={this.save}
                       />
         }
    }
// etc ...
});

ChoiceFields.js.jsx:

var ChoiceFields = React.createClass({
    render: function() {
        console.log(this.state);
        var options = this.setOptions();
        return (
            <div className="choiceFields"> 
                <h1>{this.props.title}</h1> 
                <SearchBar onChange={this.onSearch} /> 
                <div className="btn-group">{options}</div> 
                <NextButton next={this.saveAndContinue} text="Set Default Values" />
            </div>
        );
    },

    setOptions: function() {
        var buttons = this.state.options;

        return buttons.map(function(choice) {
            return (
                <ChoiceButton key={choice.id} title={choice.name} 
                    description={choice.description} id={choice.id}
                    makeSelection={this.selectButton} selected={choice.selected}
                />
            );
        }.bind(this));
    }
});

当状态从1前进到2时,它会毫无问题地呈现ChoiceField。当状态从2前进到3时,它会呈现新标题,但options道具尽管给出了不同的对象,但仍保持不变。

是否有某种方法可以强制React更新道具,或以其他方式重新呈现ChoiceFields对象?

- UPDATE -

我正在将this.props.options复制到this.state.options,并使用状态来跟踪是否选择了某个选项。根据@ superfell的建议,我将对象数组保存在props中,并计算在render方法中选择了哪一个。这解决了这个问题。

2 个答案:

答案 0 :(得分:2)

根据这些注释,您要将道具复制到getInitialState中的ChoiceFields组件中。当道具更新时,getInitialState不会再次被调用,因此您将不再看待陈旧状态。您可以向ChoiceFields添加componentWillReceiveProps函数,该函数可以从新道具更新状态。或者你可以重构不要将道具复制到州,因为那是一个特定的anti-pattern called out by React

答案 1 :(得分:1)

您可以使用的另一个选项是为您的ChoiceField变体提供不同的密钥,因此React会知道它们是不同的实例,并且当您在后续渲染中交换它们时,它们将获得完整的组件生命周期: / p>

        case 2:
            return <ChoiceFields 
                        key="first"
                        title="Choose first thing:"
                        field="first_id"
                        options={this.state.firstChoices}
                        nextStage={this.nextStage}
                        save={this.save}
                    />
        case 3:
            return <ChoiceFields 
                        key="second"
                        title="Choose second thing:"
                        field="second_id"
                        options={this.state.secondChoices}
                        nextStage={this.nextStage}
                        save={this.save}
                   />

React.js and Dynamic Children - Why the Keys are Important很好地解释了正在发生的事情以及相关文档的链接。