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

Posted

技术标签:

【中文标题】在 React 中使用多个选项从 <select> 中检索值【英文标题】:Retrieving value from <select> with multiple option in React 【发布时间】: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>
    );
  
);

【问题讨论】:

【参考方案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)); 

【讨论】:

这很好,但HTMLCollectionOf&lt;HTMLOptionElement&gt; 不是一个数组... 显然Array.from 可以工作。 ***.com/a/49684109/29182【参考方案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),它就不能真正使用。

以上是关于在 React 中使用多个选项从 <select> 中检索值的主要内容,如果未能解决你的问题,请参考以下文章

如何有多个反应选择选项

如何使用 React 测试库从选择列表中选择一个选项

两个handleChange事件在react js中使用多个select选项

从 React 中的同一个选择下拉表单字段中获取多个值

在 Django 中检索多个选择选项时出错

如何从单个反应组件中调用多个 graphql 突变?