【问题标题】:React JS Radio input stateReact JS Radio 输入状态
【发布时间】:2017-09-06 02:50:01
【问题描述】:

使用 React 管理单选框和复选框状态的正确方法是什么?

在某些情况下,表单会呈现为部分完成,因此在首次加载时会预先选择一些单选框和复选框。

我有以下代码 sn-p,但我无法让它按预期工作。

    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

【问题讨论】:

    标签: forms reactjs radio-button react-jsx


    【解决方案1】:

    最重要的是让Radio 组件处理状态,并跟踪所选选项。

    此外,我将通过使用map 而不是forEach 来简化,并在Option 组件之前为返回&lt;input type='radio'&gt; 的类方法。为简单起见,使用选项 value 而不是 index 来跟踪所选状态,并模仿 React 的 select 组件允许默认的 value 道具而不是设置每个选项的 selected 道具(你好像没用)。

    最后,为了方便起见,将Radio:s radio 属性重命名为(IMO)更正确的options。 Ergo(警告,我没有测试过这个):

    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')
    );
    

    【讨论】:

      【解决方案2】:

      非常感谢您对 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>

      【讨论】:

        猜你喜欢
        • 2021-11-02
        • 2016-07-14
        • 2023-01-03
        • 2017-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-31
        • 2015-07-20
        相关资源
        最近更新 更多