Abrufen des Werts von <Auswahl> mit mehreren Optionen in Reagieren


79

Die Reaktionsmethode zum Festlegen, welche Option für ein Auswahlfeld ausgewählt wird, besteht darin, eine spezielle valueRequisite für sich <select>selbst festzulegen, die dem valueAttribut für das <option>Element entspricht, das Sie auswählen möchten. Für eine multipleAuswahl kann diese Requisite stattdessen ein Array akzeptieren.

Nun , da dies ein spezielles Attribut ist, ich frage mich , was der kanonische Weg ist , um Abrufen der ausgewählten Optionen im gleichen Array-of-Option-Werte-Struktur , wenn der Benutzer der Dinge ändert (so dass ich es durch einen Rückruf an einen passieren kann übergeordnete Komponente usw.), da vermutlich nicht dieselbe valueEigenschaft für das DOM-Element verfügbar ist.

Um ein Beispiel zu verwenden, würden Sie mit einem Textfeld Folgendes tun (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} />;
  }
});

Was ist das Äquivalent ???für diese Mehrfachauswahlkomponente?

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

Antworten:


21

Mit Array.from()und können e.target.selectedOptionsSie ein kontrolliertes Select-Multiple durchführen:

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

target.selectedOptions gibt eine HTMLCollection zurück

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


Irgendwelche Ideen, wie man die ausgewählten Optionen aus mehreren selects in einem Array kombiniert ? Sagen Sie, nachdem Sie sie alle über ergriffen haben document.querySelectorAll('select')?
Casimir

Beachten Sie, dass diese Frage zu dem Zeitpunkt gestellt wurde, selectedOptionskeine gute Kompatibilität aufwies und vom IE immer noch nicht unterstützt wird. Dies wäre jedoch der moderne Weg, dies zu tun.
Inkling

107

Genauso wie anderswo, da Sie mit dem realen DOM-Knoten als Ziel des Änderungsereignisses arbeiten:

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-Version:(option.value for option in e.target.options when option.selected)
1j01

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

4
Sie können auch die ES6-Pfeile zerstören:[...e.target.options].filter(({selected}) => selected).map(({value}) => value)
Mathieu M-Gosselin

6
RE: ES6-Version, obwohl das richtig aussieht , funktioniert es nicht. event.target.optionsist ein HTMLOptionsCollection, kein Array.
TrueWill

3
@ Zrisher Negativ, Ghost Rider. HTMLOptionsCollectionist nicht iterierbar. Funktioniert jedoch Array.fromimmer noch damit: Array.from(event.target.options).filter(o => o.selected).map(o => o.value)
Bondolin


11

Wenn Sie verwenden möchten, refkönnen Sie ausgewählte Werte wie folgt erhalten:

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

ES6- Update 2018

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

1
Ich werde dies auch verwenden, um meine Antwort zu ersetzen, da selectedOptionsdies in IE
Rambossa am

Hier ist eine viel sauberere, es6-Methode :) [] .filter.call (this.refs.selectRef.options, o => o.selected) .map (o => o.value);
Dg Jacquard

7

In dem Fall, dass Sie die ausgewählten Optionen verfolgen möchten, während das Formular ausgefüllt wird:

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

selectedOptionsist eine Array-ähnliche Sammlung / Liste von Elementen, die sich auf das DOM beziehen. Sie erhalten im Ereigniszielobjekt Zugriff darauf, wenn Sie Optionswerte auswählen. Array.prototype.sliceund callermöglicht es uns, eine Kopie davon für den neuen Zustand zu erstellen. Sie können auf diese Weise auch mit einem Verweis auf die Werte zugreifen (falls Sie das Ereignis nicht erfassen). Dies war eine weitere Antwort auf die Frage.


2
Wie in einem meiner anderen Kommentare erwähnt, selectedOptionsscheint die Browserunterstützung für ziemlich lückenhaft zu sein. Aber es wäre wahrscheinlich die ideale Lösung, wenn die Unterstützung da wäre.
Inkling

1
Ah wahr, es scheint, als ob IE dies immer noch nicht unterstützt
Rambossa

6

Sie können das selectedOptionsInnere des Ziels tatsächlich finden ... Sie müssen nicht alle Optionen durchlaufen. Stellen Sie sich vor, Sie möchten die Werte onChangeals Requisiten an eine an Ihre Komponente übergebene Funktion senden : Sie können die folgende Funktion für die onChangeMehrfachauswahl verwenden.

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

Zu der Zeit, als diese Frage gestellt wurde, selectedOptionshatte keine gute Kompatibilität. Es wird von Internet Explorer immer noch nicht unterstützt und ist daher nicht wirklich verwendbar, wenn Sie IE-Unterstützung wünschen (zumindest ohne Polyfill).
Inkling

3

Folgendes hat bei mir funktioniert

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

1
Richtig, ich habe JQuery verwendet, um die mehreren Werte abzurufen.
Mantish

Sie müssen weder Dom noch jQuery reagieren. Rufen Sie einfach den Wert aus dem onChange-Ereignis ab
jamesmfriedman

1

Ein anderer Weg, es zu tun:

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

0

Probier diese:

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>

Fügen Sie Ihren Lösungen weitere Erklärungen hinzu.
Manmohan_singh
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.