在React中使用多个选项从<select>检索值


79

设置选择框选择哪个选项的反应方式是value在其<select>自身上设置一个特殊的道具,与要选择value<option>元素上的属性相对应。对于multiple选择,该道具可以接受数组。

现在,因为这是一个特殊属性,所以我想知道当用户更改内容时,在相同的option-values-values结构中检索选定选项的规范方法是什么(因此我可以将其通过回调传递给父组件等),因为推测相同的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>
    );
  }
});

Answers:


21

使用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


关于如何将多个中select的所选选项组合到一个数组中的任何想法?说完都通过抓住了document.querySelectorAll('select')吗?
卡西米尔,

请注意,在问这个问题时,它selectedOptions没有很好的兼容性,IE仍然不支持。不过,这将是现代的方式。
暗示

107

因为您将真实的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);
}

4
CoffeeScript版本:(option.value for option in e.target.options when option.selected)
1j01年

63
ES6版本:[... event.target.options] .filter(o => o.selected).map(o => o.value)
svachalek

4
您也可以破坏ES6箭头:[...e.target.options].filter(({selected}) => selected).map(({value}) => value)
Mathieu M-Gosselin

6
RE:ES6版本,虽然看起来正确,但无法使用。event.target.optionsHTMLOptionsCollection,而不是Array。
TrueWill

3
@zrisher负面,幽灵骑士。 HTMLOptionsCollection是不可迭代的。但是,Array.from仍然可以使用: Array.from(event.target.options).filter(o => o.selected).map(o => o.value)
Bondolin


11

如果您想使用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);

1
也会用它代替我的答案,因为selectedOptionsIE不支持
rambossa

这是一种更清洁的es6方法:) [] .filter.call(this.refs.selectRef.options,o => o.selected).map(o => o.value);
Dg提花

7

在这种情况下,您希望在填写表格时跟踪选定的选项:

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来访问值(以防万一您没有捕获事件),这是该问题的另一个答案。


2
正如我在其他评论中提到的那样,浏览器支持selectedOptions似乎很粗略。但是,如果有支持的话,那可能是理想的解决方案。
2013年

1
嗯,是的,看来IE仍然不支持此功能
rambossa

6

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

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

在问这个问题的时候,selectedOptions并没有很好的兼容性。Internet Explorer仍然不支持此功能,因此,如果要IE支持(至少没有polyfill),则不能真正使用。
暗示

3

以下为我工作

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

1
正确,我使用JQuery来检索多个值。
螳螂

您不需要React dom或jQuery。只需检索onChange事件的价值
jamesmfriedman

1

另一种方法是:

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

0

试试这个:

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>

在您的解决方案中添加更多说明。
Manmohan_singh '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.