2017-04-10 33 views
0

使用React管理無線電和複選框狀態的正確方法是什麼?React JS無線電輸入狀態

在某些情況下,表格會呈現部分完成狀態,因此某些無線電和複選框會在第一次加載時被預選。

我有下面的代碼片段,我無法讓它按預期工作。

var formData = { 
    "id": 13951, 
    "webform_id": 1070, 
    "page": 0, 
    "type": "radios", 
    "name": "What industry are you in?", 
    "tooltip": "", 
    "weight": 0, 
    "is_required": 1, 
    "default_value": "", 
    "validation": "", 
    "allow_other_option": 0, 
    "other_option_text": "", 
    "mapped_question_id": "a295189e-d8b4-11e6-b2c5-022a69d30eef", 
    "created_at": "2017-04-07 18:40:39", 
    "updated_at": "2017-04-07 18:40:39", 
    "option_conditional_from": null, 
    "default_value_querystring_key": "", 
    "deleted_at": null, 
    "is_auto_save": 0, 
    "is_component_number_hidden": 0, 
    "is_component_inline": 0, 
    "enable_confirm_validation": 0, 
    "confirm_validation_text": null, 
    "additional_options": "", 
    "url_mapping": "", 
    "webformcomponentoptions": [ 
    { 
     "id": 13888, 
     "webform_component_id": 13951, 
     "key": "Hospitality", 
     "value": "Hospitality", 
     "created_at": "2017-04-07 18:40:39", 
     "updated_at": "2017-04-07 18:40:39", 
     "group": "", 
     "selected" : false 
    }, 
    { 
     "id": 13889, 
     "webform_component_id": 13951, 
     "key": "Retail", 
     "value": "Retail", 
     "created_at": "2017-04-07 18:40:39", 
     "updated_at": "2017-04-07 18:40:39", 
     "group": "", 
     "selected" : false 
    }, 
    { 
     "id": 13890, 
     "webform_component_id": 13951, 
     "key": "Other", 
     "value": "Other", 
     "created_at": "2017-04-07 18:40:39", 
     "updated_at": "2017-04-07 18:40:39", 
     "group": "", 
     "selected" : false 
    } 
    ] 
} 

class WebformApp extends React.Component { 
    render() { 
    return (
     <form> 
     <label>{this.props.webform.name}</label> 
     <div className="group-wrapper"> 
      <Radio radio={this.props.webform.webformcomponentoptions} /> 
     </div> 
     </form> 
    ) 
    } 
} 

class Radio extends React.Component { 
    render() { 
    var options = []; 
    this.props.radio.forEach(function(radio, i) { 
     options.push(<Option option={radio} key={radio.id} index={i} />); 
    }) 
    return (
     <div>{options}</div> 
    ) 
    } 
} 

class Option extends React.Component { 
    constructor(props) { 
    super(props); 
    this.handleOptionChange = this.handleOptionChange.bind(this); 
    this.state = {selectedIndex: null}; 
    } 

    handleOptionChange(e) { 
    this.setState({selectedIndex: this.props.index}, function() { 
    }); 
    } 

    render() { 
    const selectedIndex = this.state.selectedIndex; 
    return (
     <div> 
     <input type="radio" 
      value={this.props.option.value} 
      name={this.props.option.webform_component_id} 
      id={this.props.option.id} 
      checked={selectedIndex === this.props.index} 
      onChange={this.handleOptionChange} /> 
     <label htmlFor={this.props.option.id}>{this.props.option.key}</label> 
     </div> 
    ) 
    } 
} 

ReactDOM.render(
    <WebformApp webform={formData} />, 
    document.getElementById('app') 
); 

https://codepen.io/jabreezy/pen/KWOyMb

回答

0

最重要的事情是有Radio組件處理狀態,以及所選擇的選項的跟蹤。

此外,我會通過使用map代替forEach,和前述的Option組件,其用於一個類方法返回一個<input type='radio'>簡化。爲了簡單起見,使用選項value來跟蹤所選狀態而不是index,並且模仿React的select組件允許默認value道具,而不是設置每個選項的selected道具(您似乎沒有使用)。

最後,爲了訂單的緣故,將Radio:s radio支柱重命名爲(IMO)更正確的options。埃爾戈(注意,我沒有測試過):

class WebformApp extends React.Component { 
    render() { 
    return (
     <form> 
     <label>{this.props.webform.name}</label> 
     <div className="group-wrapper"> 
      <Radio options={this.props.webform.webformcomponentoptions} value={this.props.webform.value} /> 
     </div> 
     </form> 
    ) 
    } 
} 

class Radio extends React.Component { 
    constructor (props) { 
    super(props) 

    this.handleOptionChange = this.handleOptionChange.bind(this) 
    this.state = {value: this.props.value} 
    } 

    render() { 
    return this.props.options.map(this.getOption) 
    } 

    handleOptionChange (e) { 
    this.setState({value: e.target.value}) 
    } 

    getOption (option) { 
    return (
     <div> 
     <input type='radio' 
      value={option.value} 
      name={option.webform_component_id} 
      id={option.id} 
      key={option.id} 
      checked={this.state.value === option.value} 
      onChange={this.handleOptionChange} /> 
     <label htmlFor={option.id}>{option.key}</label> 
     </div> 
    ) 
    } 
} 

ReactDOM.render(
    <WebformApp webform={formData} />, 
    document.getElementById('app') 
); 
0

非常感謝您的輸入Linus。你讓我沿着正確的路徑和我已經解決了我的問題,通過以下方式:

var formData = { 
 
    "id": 13951, 
 
    "webform_id": 1070, 
 
    "page": 0, 
 
    "type": "radios", 
 
    "name": "What industry are you in?", 
 
    "tooltip": "", 
 
    "weight": 0, 
 
    "is_required": 1, 
 
    "default_value": "", 
 
    "validation": "", 
 
    "allow_other_option": 0, 
 
    "other_option_text": "", 
 
    "mapped_question_id": "a295189e-d8b4-11e6-b2c5-022a69d30eef", 
 
    "created_at": "2017-04-07 18:40:39", 
 
    "updated_at": "2017-04-07 18:40:39", 
 
    "option_conditional_from": null, 
 
    "default_value_querystring_key": "", 
 
    "deleted_at": null, 
 
    "is_auto_save": 0, 
 
    "is_component_number_hidden": 0, 
 
    "is_component_inline": 0, 
 
    "enable_confirm_validation": 0, 
 
    "confirm_validation_text": null, 
 
    "additional_options": "", 
 
    "url_mapping": "", 
 
    "webformcomponentoptions": [ 
 
    { 
 
     "id": 13888, 
 
     "webform_component_id": 13951, 
 
     "key": "Hospitality", 
 
     "value": "Hospitality", 
 
     "created_at": "2017-04-07 18:40:39", 
 
     "updated_at": "2017-04-07 18:40:39", 
 
     "group": "", 
 
     "selected" : false 
 
    }, 
 
    { 
 
     "id": 13889, 
 
     "webform_component_id": 13951, 
 
     "key": "Retail", 
 
     "value": "Retail", 
 
     "created_at": "2017-04-07 18:40:39", 
 
     "updated_at": "2017-04-07 18:40:39", 
 
     "group": "", 
 
     "selected" : false 
 
    }, 
 
    { 
 
     "id": 13890, 
 
     "webform_component_id": 13951, 
 
     "key": "Other", 
 
     "value": "Other", 
 
     "created_at": "2017-04-07 18:40:39", 
 
     "updated_at": "2017-04-07 18:40:39", 
 
     "group": "", 
 
     "selected" : false 
 
    } 
 
    ] 
 
} 
 

 
class WebformApp extends React.Component { 
 
    render() { 
 
    return (
 
     <form> 
 
     <label>{this.props.webform.name}</label> 
 
     <div className="group-wrapper"> 
 
      <Radio radio={this.props.webform.webformcomponentoptions} /> 
 
     </div> 
 
     </form> 
 
    ) 
 
    } 
 
}; 
 

 
class Radio extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    this.state = {selectedOption: 'Other'}; 
 
    } 
 

 
    handleOptionChange(changeEvent) { 
 
    this.setState({ 
 
     selectedOption: changeEvent.target.value 
 
    }) 
 
    }; 
 

 
    renderOption(props) { 
 
    return (
 
     <div> 
 
     <h3>{props.index}</h3> 
 
     <input type="radio" 
 
      value={props.option.value} 
 
      name={props.option.webform_component_id} 
 
      id={props.option.id} 
 
      checked={props.status} 
 
      onChange={props.clickeme} /> 
 
     <label htmlFor={props.option.id}>{props.option.key}</label> 
 
     </div> 
 
    ) 
 
    }; 
 

 
    render() { 
 
    return (
 
     <div> 
 
     {this.props.radio.map(function(radio) { 
 
      var selected = this.state.selectedOption === radio.value; 
 
      return <this.renderOption option={radio} key={radio.value} status={selected} clickeme={(e)=> this.handleOptionChange(e)} />; 
 
     }, this)} 
 
     </div> 
 
    ) 
 
    }; 
 
}; 
 

 
ReactDOM.render(
 
    <WebformApp webform={formData} />, 
 
    document.getElementById('app') 
 
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="app"></div>