Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React.js在呈现子类时不间断地重用数据reactid_Javascript_Reactjs - Fatal编程技术网

Javascript React.js在呈现子类时不间断地重用数据reactid

Javascript React.js在呈现子类时不间断地重用数据reactid,javascript,reactjs,Javascript,Reactjs,我有一个问卷对象,它呈现了几个问卷选项子类。当父问卷对象中的状态更改时,将呈现新的问卷选项子类 QuestionnaireOption类在其是否“选中”时保持状态 问题:当我更改父类中的状态以呈现新的“Option”节点时,新节点被分配相同的数据反应id,我希望Option节点重置其内部状态,但它没有被分配新id,并且它包含错误的状态(在本例中,尽管使用新数据设置了道具,但在新对象上,selected仍设置为true) 我能做些什么来解决这个问题 以下是相关代码: QuestionnaireOp

我有一个
问卷
对象,它呈现了几个
问卷选项
子类。当父
问卷
对象中的状态更改时,将呈现新的
问卷选项
子类

QuestionnaireOption
类在其是否“选中”时保持状态

问题:当我更改父类中的状态以呈现新的“Option”节点时,新节点被分配相同的
数据反应id
,我希望Option节点重置其内部状态,但它没有被分配新id,并且它包含错误的状态(在本例中,尽管使用新数据设置了道具,但在新对象上,
selected
仍设置为true)

我能做些什么来解决这个问题

以下是相关代码:

QuestionnaireOption = React.createClass({
    getInitialState: function() {
        return {selected: false}
    },
    handleClick: function(e) {
        e.preventDefault();
        this.setState({selected: !this.state.selected});
    },
    render: function() {
        var fullClassName = "questionnaireOption " + (this.state.selected? "selected": "unselected");
        return (
            <div className='questionnaireOptionWrapper large-4 small-4 columns'>
                <div className={fullClassName} onClick={this.handleClick}>
                    <div>{this.props.name}</div>
                </div>
            </div>
        );
    }
});

Questionnaire = React.createClass({
    getInitialState: function() {
        return {currentStage: 0}
    },
    saveOptionState: function() {
        // dump option state into amber.js or localstorage
    },
    advanceWizard: function() {
        this.saveOptionState();
        this.setState({currentStage: this.state.currentStage + 1});
    },
    rewindWizard: function() {
        this.saveOptionState();
        this.setState({currentStage: this.state.currentStage - 1});
    },
    seeResults: function() {
        console.log(globalOptionState);
    },
    render: function() {
        var currentWizardQuestion = wizardQuestions[this.state.currentStage];
        var currentOptionNodes = currentWizardQuestion.options.map(function(option) {
            node = (
                <QuestionnaireOption
                    name={option.name}
                    value={option.value}
                />
            );
            return node;
        });

        return (
            <div className="questionnaire row">
                <div className="questionnaire-question large-8 small-12 columns">
                    <div className="questionnaire-question-text">
                        {currentWizardQuestion.text}
                    </div>
                    <div className="questionnaire-question-subtext">
                        {currentWizardQuestion.subtext}
                    </div>
                    <div className="row">
                        {currentOptionNodes}
                    </div>

                    <input type="button" value="Back" onClick={this.rewindWizard}
                        style={this.state.currentStage == 0? {display: "none"}: {}
                    } />

                    <input type="button" value="Next" onClick={this.advanceWizard}
                        style={this.state.currentStage == wizardQuestions.length - 1?
                            {display: "none"}: {}
                    } />

                    <input type="button" value="Finish" onClick={this.seeResults}
                        style={this.state.currentStage < wizardQuestions.length - 1?
                            {display: "none"}: {}
                    } />
                </div>
            </div>
        );
    }
});
QuestionnaireOption=React.createClass({
getInitialState:函数(){
返回{selected:false}
},
handleClick:函数(e){
e、 预防默认值();
this.setState({selected:!this.state.selected});
},
render:function(){
var fullClassName=“questionnaireOption”+(this.state.selected?“selected”:“unselected”);
返回(
{this.props.name}
);
}
});
问卷=React.createClass({
getInitialState:函数(){
返回{currentStage:0}
},
saveOptionState:function(){
//将选项状态转储到amber.js或localstorage中
},
高级向导:函数(){
这个.saveOptionState();
this.setState({currentStage:this.state.currentStage+1});
},
倒带向导:函数(){
这个.saveOptionState();
this.setState({currentStage:this.state.currentStage-1});
},
请参见结果:函数(){
console.log(globalOptionState);
},
render:function(){
var currentWizardQuestion=wizardQuestions[this.state.currentStage];
var currentOptionNodes=currentWizardQuestion.options.map(函数(选项){
节点=(
);
返回节点;
});
返回(
{currentWizardQuestion.text}
{currentWizardQuestion.subtext}
{currentOptionNodes}
);
}
});

在控制台中,您会看到以下警告:

数组中的每个子元素都应该有一个唯一的“键”属性。请检查应用程序的渲染方法。有关详细信息,请参阅

如果您不这样做,您就没有使用开发构建:您应该修复它

React使用两种方法来确定渲染之间的内容是否“相同”:组件类(例如QuestionnaireOption)和关键道具

如果其中一个与上一个渲染不匹配,react会认为它不同,然后重新创建实例*并丢弃子树dom

假设
选项。name
可用于确定相等性,请将代码更改为:

    var currentOptionNodes = currentWizardQuestion.options.map(function(option) {
        var node = (
            <QuestionnaireOption
                name={option.name}
                value={option.value}
                key={option.name}
            />
        );
        return node;
    });
var currentOptionNodes=currentWizardQuestion.options.map(函数(选项){
变量节点=(
);
返回节点;
});

作为参考,reactid是一个实现细节,可以随时更改或删除

*如果您只是更改项目的顺序,它会尝试更改性能的顺序。目前有一些情况不会发生这种情况,因此不应该依赖它