【问题标题】:Retrieving value from <select> with multiple option in React在 React 中使用多个选项从 <select> 中检索值
【发布时间】:2015-04-21 21:11:39
【问题描述】:

设置选择框选择哪个选项的 React 方法是在 &lt;select&gt; 本身上设置一个特殊的 value 属性,对应于您希望成为的 &lt;option&gt; 元素上的 value 属性选择。对于multiple,选择此道具可以改为接受数组。

现在因为这是一个特殊属性,我想知道当用户更改内容时,检索同一数组选项值结构中的选定选项的规范方法是什么(所以我可以通过回调将它传递给父组件等),因为大概相同的 value 属性在 DOM 元素上不可用。

举个例子,你可以用一个文本字段做这样的事情(JSX):

var TextComponent = React.createClass({
  handleChange: function(e) {
    var newText = e.target.value;
    this.props.someCallbackFromParent(newText);
  },
  render: function() {
    return <input type="text" value={this.props.someText} onChange={this.handleChange} />;
  }
});

对于这个多选组件,替换 ??? 的等价物是什么?

var MultiSelectComponent = React.createClass({
  handleChange: function(e) {
    var newArrayOfSelectedOptionValues = ???;
    this.props.someCallbackFromParent(newArrayOfSelectedOptionValues);
  },
  render: function() {
    return (
      <select multiple={true} value={this.props.arrayOfOptionValues} onChange={this.handleChange}>
        <option value={1}>First option</option>
        <option value={2}>Second option</option>
        <option value={3}>Third option</option>
      </select>
    );
  }
});

【问题讨论】:

    标签: javascript dom reactjs


    【解决方案1】:

    与其他任何地方一样,因为您正在使用真实的 DOM 节点作为更改事件的目标:

    handleChange: function(e) {
      var options = e.target.options;
      var value = [];
      for (var i = 0, l = options.length; i < l; i++) {
        if (options[i].selected) {
          value.push(options[i].value);
        }
      }
      this.props.someCallback(value);
    }
    

    【讨论】:

    • CoffeeScript 版本:(option.value for option in e.target.options when option.selected)
    • ES6 版本:[...event.target.options].filter(o => o.selected).map(o => o.value)
    • 你也可以解构 ES6 箭头:[...e.target.options].filter(({selected}) =&gt; selected).map(({value}) =&gt; value)
    • RE:ES6 版本,虽然 看起来 对,但它不起作用。 event.target.optionsHTMLOptionsCollection,而不是数组。
    • @zrisher 否定,恶灵骑士。 HTMLOptionsCollection 不可迭代。但是,Array.from 仍然可以使用它:Array.from(event.target.options).filter(o =&gt; o.selected).map(o =&gt; o.value)
    【解决方案2】:

    以下对我有用

    var selectBoxObj = React.findDOMNode(this.refs.selectBox)
    var values = $(selectBoxObj).val()
    

    【讨论】:

    • 正确,我使用 JQuery 检索多个值。
    • 你不需要 react dom 或 jQuery。只需从 onChange 事件中检索值
    【解决方案3】:

    如果您想使用ref,您可以像这样获得选定的值:

    var select = React.findDOMNode(this.refs.selectRef); 
    var values = [].filter.call(select.options, function (o) {
          return o.selected;
        }).map(function (o) {
          return o.value;
        });
    

    2018 ES6更新

      let select = this.refs.selectRef;
      let values = [].filter.call(select.options, o => o.selected).map(o => o.value);
    

    【讨论】:

    • 也将使用它来代替我的答案,因为 IE 不支持 selectedOptions
    • 这是一种更简洁的 es6 方式:) [].filter.call(this.refs.selectRef.options, o => o.selected).map(o => o.值);
    【解决方案4】:

    如果您想在填写表格时跟踪所选选项:

    handleChange(e) {
        // assuming you initialized the default state to hold selected values
        this.setState({
            selected:[].slice.call(e.target.selectedOptions).map(o => {
                return o.value;
            });
        });
    }
    

    selectedOptions 是一个类似数组的集合/与 DOM 相关的元素列表。选择选项值时,您可以在事件目标对象中访问它。 Array.prototype.slicecall 允许我们为新状态创建它的副本。您还可以使用 ref 以这种方式访问​​值(以防您没有捕获事件),这是该问题的另一个答案。

    【讨论】:

    • 正如我在其他 cmets 中提到的,浏览器对 selectedOptions 的支持似乎相当粗略。但如果有支持,这可能是理想的解决方案。
    • 嗯,看来IE还是不支持这个
    【解决方案5】:

    另一种方法:

    handleChange({ target }) {
        this.props.someCallback(
           Array.prototype.slice.call(target.selectedOptions).map(o => o.value)
        )
    }
    

    【讨论】:

      【解决方案6】:

      最简单的方法...

      handleChange(evt) {
        this.setState({multiValue: [...evt.target.selectedOptions].map(o => o.value)}); 
      }
      

      【讨论】:

      【解决方案7】:

      试试这个:

      dropdownChanged = (event) => {
          let obj = JSON.parse(event.target.value);
          this.setState(
              {
                  key: obj.key,
                  selectedName: obj.name,
                  type: obj.type
              });
      }
      
      
      <select onChange={this.dropdownChanged} >
      <option value={JSON.stringify({ name: 'name', key: 'key', type: "ALL" })} >All Projetcs and Spaces</option></select>
      

      【讨论】:

      • 为您的解决方案添加更多解释。
      【解决方案8】:

      使用Array.from()e.target.selectedOptions,您可以执行受控的多选:

      handleChange = (e) => {
        let value = Array.from(e.target.selectedOptions, option => option.value);
        this.setState({values: value});
      }
      

      target.selectedOptions 返回一个 HTMLCollection

      https://codepen.io/papawa/pen/XExeZY

      【讨论】:

      • 关于如何将多个selects 中的选定选项组合到一个数组中的任何想法?全部通过document.querySelectorAll('select')抢完再说?
      • 请注意,在问这个问题的时候,selectedOptions 没有很好的兼容性,仍然不被 IE 支持。不过,这将是现代的方式。
      【解决方案9】:

      您实际上可以在目标中找到selectedOptions...无需遍历所有选项。假设您想将值发送到作为道具传递给组件的onChange 函数:您可以在多选的onChange 上使用以下函数。

      onSelectChange = (e) => {
          const values = [...e.target.selectedOptions].map(opt => opt.value);
          this.props.onChange(values);
        };
      

      【讨论】:

      • 在问这个问题的时候,selectedOptions 没有很好的兼容性。 Internet Explorer 仍然不支持它,所以如果你想要 IE 支持(至少没有 polyfill),它就不能真正使用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-17
      • 1970-01-01
      • 2020-01-01
      • 2021-05-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多