最近在一本react書上看到一個多項選擇題的react組件炎咖,做了一些改動。實現(xiàn)一個多項選擇題的組件很簡單隘擎,但是這里主要講了它的實現(xiàn)思路痢法。以下是實現(xiàn)效果:
一個渲染選擇題的組件要滿足一下幾個條件:
1.接受一組選項作為輸入。
2.把選項渲染給用戶陵且。
3.只允許用戶選擇一個選項裁僧。
HTML提供了input(radio)單選輸入框。
組件的層級從上往下看是這樣的:
MultipleChoice(多個選擇項的選擇題) ->RadioInput(一個選項) -> Input(type="radio")
選擇題組件MultipleChoice應(yīng)該由一個個基本的選項組成(RadioInput)慕购,一個選項應(yīng)該有一個輸入單選框input構(gòu)成聊疲。
組裝HTML
首先將input(type="radio")組裝到AnswerRadioInput這個組件中,
var AnswerRadioInput = React.createClass({
render: function(){
return (
<div className="checks">
<label htmlFor={this.state.id}><input type="radio" />Label text</label>
</div>
);
}
});
添加動態(tài)屬性
1.需要添加value和name值沪悲,表示傳遞的值获洲;
2.文本,這個選項是什么內(nèi)容
3.可能需要id
如此殿如,可以把這些添加到PropTypes對象當(dāng)中:
propTypes: {
id: React.PropTypes.string.isRequired,
name:React.PropTypes.string.isRequired,
label:React.PropTypes.string.isRequired,
value:React.PropTypes.string.isRequired,
checked:React.PropTypes.bool,
onChange:React.PropTypes.func.isRequired
}
數(shù)據(jù)傳入
getInitialState: function(){
var id = this.props.id;
return {
checked: false,
id: id,
name:id
};
},
handleChanged: function(e){
var checked = e.target.checked;
//to do what;
},
render: function(){
return (
<div className="checks">
<label htmlFor={this.state.id}>
<input type="radio"
name={this.props.name}
id={this.props.id}
value={this.props.value}
onChange={this.handleChanged}
/>{this.props.label}</label>
</div>
);
}
整合到父組件當(dāng)中
現(xiàn)在可以把這個組件整合到AnswerMultipleChoiceQuestion父組件中贡珊,這一層主要是渲染一列選項讓用戶從中選擇最爬。
1.需要傳入給這個單選題傳入name值
2.需要傳入給這個單選題傳入問題內(nèi)容
2.需要傳入每個選項label內(nèi)容
3.需要傳入每個選項的value值
var AnswerMultipleChoiceQuestion = React.createClass({
propTypes: {
value: React.PropTypes.string,
choices: React.PropTypes.array.isRequired
},
getInitialState: function(){
return {
id : parseInt(Math.random()*100000,10)+'i',
value: this.props.value
};
},
handleChanged: function(e){
// e.stopPropagation();
},
renderChoices: function(){
return this.props.choices.map(function(choice,i){
return <AnswerRadioInput key={i} id={'choice-'+i} name={this.props.value} label={choice} value={this.props.choiceValue[i]} onChange={this.handleChanged}/>;
}.bind(this));
},
render: function(){
return (
<div className="form-group">
<label className="survey-item-label" htmlFor={this.state.id}>
{this.props.label}
</label>
<div className="survey-item-content">
{this.renderChoices()}
</div>
</div>
);
}
});
現(xiàn)在只需要把這個組件暴露出來
module.exports = AnswerMultipleChoiceQuestion;
應(yīng)用
ReactDOM.render(<AnswerMultipleChoiceQuestion value={'fruit'} label={'最喜歡的水果是哪一個'} choices={['a.蘋果','b.西瓜','d.香蕉','d.葡萄']}/>,document.getElementById('wrapper'));
這樣只能生產(chǎn)一個選擇題,如果想要生產(chǎn)多個選擇題飞崖,像開始圖片展示那樣烂叔,則可以再多生成一個父組件。將這個AnswerMultipleChoiceQuestion整合到這個父組件中固歪。
1.需要傳入每道選擇題的問題內(nèi)容label蒜鸡;
2.需要傳入每個選項的name值;
3.需要傳入每個選項的內(nèi)容label;
4.需要傳入每個選項的value值牢裳;
5.可以考慮傳入這些選擇題的標(biāo)題title;
var ReactDOM = require('react-dom');
var React = require('react');
var AnswerMultipleChoiceQuestion = require('./Choice.jsx');
var MoreChoicesQuestion = React.createClass({
propTypes: {
values: React.PropTypes.array.isRequired,
title: React.PropTypes.string.isRequired,
labelArray: React.PropTypes.array.isRequired,
choiceArray: React.PropTypes.array.isRequired
},
renderMore: function(){
return this.props.choiceArray.map(function(choices,i){
return <AnswerMultipleChoiceQuestion key={'question'+i} value={this.props.values[i]} label={this.props.labelArray[i]} choiceValue={this.props.choicesValue[i]} choices={choices}/>;
}.bind(this));
},
render: function(){
return (
<div className="question-wrapper">
<h3>{this.props.title}</h3>
<div className="questions">
{
this.renderMore()
}
</div>
</div>
);
}
});
ReactDOM.render(<MoreChoicesQuestion values={['fruit','country','subject']} title={'個人喜好調(diào)查問卷'} labelArray={['1.以下最喜歡的水果是哪一個逢防?','2.以下最喜歡的國家是哪一個?','3.以下最喜歡的科目是哪一個?']} choiceArray={[['a.蘋果','b.西瓜','c.香蕉','d.葡萄'],['a.中國','b.法國','c.英國','d.美國'],['a.數(shù)學(xué)','b.英語','c.語文','d.物理']]} choicesValue={[['apple','watermelon','banana','grape'],['China','France','England','America'],['math','English','chinese','physics']]}/>,document.getElementById('wrapper'));
表達有點亂~~~