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

IT技术 javascript dom reactjs
2021-03-20 14:11:20

React 设置选择框选择哪个选项的方法,是value在其<select>自身设置一个特殊的prop ,对应于您希望被选择value<option>元素上的属性对于multiple选择,这个props可以接受一个数组。

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

与您在其他任何地方所做的相同,因为您使用真实的 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);
}
您还可以解构 ES6 箭头: [...e.target.options].filter(({selected}) => selected).map(({value}) => value)
2021-04-23 14:11:20
CoffeeScript 版本: (option.value for option in e.target.options when option.selected)
2021-04-30 14:11:20
@zrisher 否定,幽灵骑士。 HTMLOptionsCollection不可迭代。但是,Array.from仍然可以使用它: Array.from(event.target.options).filter(o => o.selected).map(o => o.value)
2021-05-08 14:11:20
ES6 版本:[...event.target.options].filter(o => o.selected).map(o => o.value)
2021-05-11 14:11:20
RE:ES6 版本,虽然看起来正确但不起作用。event.target.options是一个HTMLOptionsCollection,而不是一个数组。
2021-05-12 14:11:20

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

请注意,当时提出此问题,selectedOptions兼容性不佳,并且 IE 仍然不支持。不过,这将是现代的方法。
2021-05-10 14:11:20
关于如何将多个selects 中的选定选项组合到一个数组中的任何想法在通过document.querySelectorAll('select')?
2021-05-15 14:11:20

最简单的方法...

handleChange(evt) {
  this.setState({multiValue: [...evt.target.selectedOptions].map(o => o.value)}); 
}
这很好,但HTMLCollectionOf<HTMLOptionElement>不是数组......Array.from虽然显然有效。stackoverflow.com/a/49684109/29182
2021-04-25 14:11:20

如果您想使用,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);
也将使用它来代替我的答案,因为selectedOptionsIE 不支持
2021-05-10 14:11:20
这是一种更简洁的 es6 方法:) [].filter.call(this.refs.selectRef.options, o => o.selected).map(o => o.value);
2021-05-16 14:11:20

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

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

啊对了,IE好像还不支持这个
2021-05-05 14:11:20
正如我在另一条评论中提到的,浏览器对 的支持selectedOptions似乎很粗略。但如果有支持,这可能是理想的解决方案。
2021-05-06 14:11:20