多項選擇題組件--react

最近在一本react書上看到一個多項選擇題的react組件,做了一些改動。實現(xiàn)一個多項選擇題的組件很簡單,但是這里主要講了它的實現(xiàn)思路。以下是實現(xiàn)效果:

1508762957.jpg

一個渲染選擇題的組件要滿足一下幾個條件:
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'));

表達(dá)有點亂~~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容