首先是一些背景,我正在研究调查问卷并决定开始学习React.js。问卷的每一步都包括一个问题和是/否单选按钮组,以及导航按钮。这是jsfiddle。问题组件非常简单,我在父组件中传递formData并将数据函数保存到它。
问题组件的代码
var Question = React.createClass({
getInitialState: function() {
return {
}
},
createMarkup: function(html) {
return {
__html: html
};
},
render: function() {
var subtitle = this.props.subtitle || '';
var name = this.props.name;
if (this.props.formData[name] === undefined) {
var answer_yes = null;
var answer_no = null;
} else {
answer_yes = this.props.formData[name] == "yes" ? true : null;
answer_no = this.props.formData[name] == "no" ? true : null;
}
console.log(answer_yes);
console.log(answer_no);
return (
<div className="container-question">
<label className="default" dangerouslySetInnerHTML={this.createMarkup(this.props.question)}></label>
<span className="alert subtitle" dangerouslySetInnerHTML={this.createMarkup(subtitle)}></span>
<div className="form-group form-group-radio">
<div className="row">
<div className="col-xs-4">
<input type="radio" id={name + "_yes"} name={name} value="yes" defaultChecked={answer_yes} onChange={this.props.saveData}/><label htmlFor="yes">Yes</label><br></br>
<input type="radio" id={name + "_no"} name={name} value="no" defaultChecked={answer_no} onChange={this.props.saveData}/><label htmlFor="no">No</label>
</div>
</div>
</div>
</div>
);
}
});
问题在于,当您在第一个问题上选择答案并单击下一个时,第二个问题的无线电控制会随之改变,当您第一个回答第二个问题时也会发生同样的事情。我将defaultChecked的布尔变量存储为渲染函数中的局部变量,并将它们记录在控制台中。
我有没有明显的错误?任何帮助表示赞赏。
答案 0 :(得分:2)
这是一个更新的jsfiddle:https://jsfiddle.net/69z2wepo/8365/
问题在于您正在使用所谓的“不受控制的组件”。在React。有关详细信息,请参阅此页:https://facebook.github.io/react/docs/forms.html
更改为您的方案的受控组件意味着使用checked
而不是defaultChecked
。 defaultChecked
适用于不受控制的组件,其中输入控件的值(在您的情况下为单选按钮)不受组件的props
或render
方法控制。 React确实设计为使用受控组件,其中props
/ state
/ render
正好驱动用户界面显示的内容。
从使用defaultChecked
更改为checked
时,您首先注意到的是您将无法再更改UI中的无线电状态。发生这种情况的原因是,虽然您的saveData
函数中的应用程序状态发生了变化,但您的组件未被重新渲染。
处理此问题有几种不同的方法。更新后的jsfiddle将在saveData
期间重新呈现您的应用程序。理想情况下,这应该是不同的因素。 saveData
应移出父组件并进入FormDataStore
概念(请参阅React Flux体系结构,https://facebook.github.io/flux/docs/overview.html)或父组件应拥有formData
状态,在setState
中调用saveData
,这将导致重新呈现DOM树的该部分。