JSX reagieren: Wählen Sie bei der ausgewählten Option <Auswahl> die Option „Ausgewählt“

402

In einer React-Komponente für ein <select>Menü muss das selectedAttribut für die Option festgelegt werden, die den Anwendungsstatus widerspiegelt.

In render()dem optionStatevon dem Zustand Eigentümer an die SortMenu Komponente übergeben. Die Optionswerte werden propsab JSON übergeben.

render: function() {
  var options = [],
      optionState = this.props.optionState;

  this.props.options.forEach(function(option) {
    var selected = (optionState === option.value) ? ' selected' : '';

    options.push(
      <option value={option.value}{selected}>{option.label}</option>
    );
  });

// pass {options} to the select menu jsx

Dies löst jedoch einen Syntaxfehler bei der JSX-Kompilierung aus.

Dadurch wird der Syntaxfehler beseitigt, das Problem wird jedoch offensichtlich nicht gelöst:

var selected = (optionState === option.value) ? 'selected' : 'false';

<option value={option.value} selected={selected}>{option.label}</option>

Ich habe es auch versucht:

var selected = (optionState === option.value) ? true : false;

<option value={option.value} {selected ? 'selected' : ''}>{option.label}</option>

Gibt es eine empfohlene Lösung?

Cantera
quelle
Upvoting der Frage nur für den Titel
Ericgio

Antworten:

648

React versteht automatisch Boolesche Werte für diesen Zweck, sodass Sie einfach schreiben können (Hinweis: nicht empfohlen)

<option value={option.value} selected={optionsState == option.value}>{option.label}</option>

und es wird 'ausgewählt' entsprechend ausgegeben.

React macht dies jedoch noch einfacher für Sie. Anstatt selectedjede Option zu definieren, können (und sollten) Sie einfach value={optionsState}auf das Auswahl-Tag selbst schreiben :

<select value={optionsState}>
  <option value="A">Apple</option>
  <option value="B">Banana</option>
  <option value="C">Cranberry</option>
</select>

Weitere Informationen finden Sie im Dokument React select tag .

Sophie Alpert
quelle
56
Mit der aktuellen Version von React (0.9) funktioniert das Einstellen des ausgewählten Attributs für Optionen überhaupt nicht. Legen Sie stattdessen das Wertattribut für das Auswahlelement fest.
Liammclennan
2
Ich lade Daten mit ajax.defaultValue funktioniert nicht für mich. Der Wert funktioniert, aber ich kann kein anderes Element in der Auswahlliste auswählen. Die Liste wird geöffnet, aber wenn ich eines davon auswähle, wird das Wertelement ausgewählt. Irgendeine Idee?
user1924375
5
@ user1924375 Sie sollten das Ereignis onChange verwenden onChange={this.handleSelect}und den Statuswert für Ihre Komponente festlegen, z. B.: 'handleSelect: function () {this.setState ({value: event.target.value});} `Dies würde Ihre ausgewählte Komponente mit new neu rendern Ausgewähltes Objekt. Hoffe es würde dir helfen.
Funnydaredevil
1
Obwohl es noch nicht dokumentiert ist, kann die valueRequisite auf a <select>ein Array sein, wenn Sie multiselectaktiviert haben.
Tirdadc
4
Verwenden Sie lieber defaultValuezu initialisieren
Dewwwald
70

Sie können das tun, was React Sie warnt, wenn Sie versuchen, die "ausgewählte" Eigenschaft von <option>:

Verwenden Sie die defaultValueoder valueRequisiten auf , <select>anstatt Einstellung selectedauf <option>.

So können Sie options.valueauf der defaultValueIhrer Auswahl verwenden

Philippe Santana
quelle
9
Wie würde ich dies tun, wenn ich dennoch die aktuell ausgewählte Option angeben möchte? Die einzige Möglichkeit, die Option derzeit tatsächlich beizubehalten (und den Status des Formulars für zukünftige POSTs beizubehalten), besteht darin, select = true zu setzen. Ich habe versucht, den Standardwert und die Wertrequisiten des Auswahlelements festzulegen, dies wird jedoch in der Ansicht nicht gerendert, indem die richtige Option im Optionsmenü ausgewählt wird. Irgendein Rat?
Die Rattenfänger
4
Beispiel vielleicht?
Shinzou
1
Funktioniert nicht für mich: <select className = "form-control" value = "Mois">
Kuartz
2
defaultValue funktioniert nicht mit der neuesten Version
Hos Mercury
18

Hier ist eine vollständige Lösung, die die beste Antwort und die Kommentare darunter enthält (was jemandem helfen könnte, der Schwierigkeiten hat, alles zusammenzusetzen):

UPDATE FOR ES6 (2019) - Verwenden von Pfeilfunktionen und Objektzerstörung

in der Hauptkomponente:

class ReactMain extends React.Component {

  constructor(props) {
    super(props);
    this.state = { fruit: props.item.fruit };
  }

  handleChange = (event) => {
    this.setState({ [event.target.name]: event.target.value });
  }

  saveItem = () => {
    const item = {};
    item.fruit = this.state.fruit;
    // do more with item object as required (e.g. save to database)
  }

  render() {
    return (
      <ReactExample name="fruit" value={this.state.fruit} handleChange={this.handleChange} />
    )
  }

}

enthaltene Komponente (die jetzt eine zustandslose Funktion ist):

export const ReactExample = ({ name, value, handleChange }) => (
  <select name={name} value={value} onChange={handleChange}>
    <option value="A">Apple</option>
    <option value="B">Banana</option>
    <option value="C">Cranberry</option>
  </select>
)

VORHERIGE ANTWORT (mit bind):

in der Hauptkomponente:

class ReactMain extends React.Component {

  constructor(props) {
    super(props);
    // bind once here, better than multiple times in render
    this.handleChange = this.handleChange.bind(this);
    this.state = { fruit: props.item.fruit };
  }

  handleChange(event) {
    this.setState({ [event.target.name]: event.target.value });
  }

  saveItem() {
    const item = {};
    item.fruit = this.state.fruit;
    // do more with item object as required (e.g. save to database)
  }

  render() {
    return (
      <ReactExample name="fruit" value={this.state.fruit} handleChange={this.handleChange} />
    )
  }

}

enthaltene Komponente (die jetzt eine zustandslose Funktion ist):

export const ReactExample = (props) => (
  <select name={props.name} value={props.value} onChange={props.handleChange}>
    <option value="A">Apple</option>
    <option value="B">Banana</option>
    <option value="C">Cranberry</option>
  </select>
)

Die Hauptkomponente behält den ausgewählten Wert für Obst bei (im Status), die enthaltene Komponente zeigt das Auswahlelement an und Aktualisierungen werden an die Hauptkomponente zurückgegeben, um ihren Status zu aktualisieren (die dann zur eingeschlossenen Komponente zurückkehrt, um den ausgewählten Wert zu ändern).

Beachten Sie die Verwendung einer Namensstütze, mit der Sie unabhängig von ihrem Typ eine einzelne handleChange-Methode für andere Felder im selben Formular deklarieren können.

Andy Lorenz
quelle
Beachten Sie, dass die Zeile im Konstruktor this.handleChange.bind(this);sein sollte this.handleChange = this.handleChange.bind(this);
Will Shaver
für diejenigen von euch wie mich, die sich selbst fragen, was das bedeutet ... reactjs.org/docs/jsx-in-depth.html#spread-attributes
talsibony
@talsibony - das ist zwar der Spread-Operator, aber in meinem Beispielcode bedeutet dies nur, dass Sie hier einen anderen Code einfügen !
Andy Lorenz
@AndyLorenz Also in diesem Fall würde ich empfehlen, es zu entfernen ... :), oder schreiben Sie einfach einen Kommentar wie // Rest Ihres Codes
Talsibony
8

Hier ist das neueste Beispiel dafür. Aus Reaktionsdokumenten sowie der automatisch bindenden Syntax der "Fettpfeil" -Methode.

class FlavorForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: 'coconut'};
  }

  handleChange = (event) =>
    this.setState({value: event.target.value});

  handleSubmit = (event) => {
    alert('Your favorite flavor is: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Pick your favorite flavor:
          <select value={this.state.value} onChange={this.handleChange}>
            <option value="grapefruit">Grapefruit</option>
            <option value="lime">Lime</option>
            <option value="coconut">Coconut</option>
            <option value="mango">Mango</option>
          </select>
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
} 
Rahil Ahmad
quelle
4

Fügen Sie einfach als erste Option Ihres ausgewählten Tags hinzu:

<option disabled hidden value=''></option>

Dies wird zur Standardeinstellung und wenn Sie eine gültige Option auswählen, wird dies auf Ihren Status abgestimmt

Pietro Allievi
quelle
1
***Html:***
<div id="divContainer"></div>

var colors = [{ Name: 'Red' }, { Name: 'Green' }, { Name: 'Blue' }];
var selectedColor = 'Green';

ReactDOM.render(<Container></Container>, document.getElementById("divContainer"));

var Container = React.createClass({
    render: function () {
        return (
        <div>            
            <DropDown data={colors} Selected={selectedColor}></DropDown>
        </div>);
    }
});

***Option 1:***
var DropDown = React.createClass(
{
    render: function () {
        var items = this.props.data;
        return (
        <select value={this.props.Selected}>
            {
                items.map(function (item) {
                    return <option value={item.Name }>{item.Name}</option>;
                })
            }
        </select>);
    }
});

***Option 2:***
var DropDown = React.createClass(
{
    render: function () {
        var items = this.props.data;
        return (
        <select>
            {
                items.map(function (item) {
                    return <option value={item.Name} selected={selectedItem == item.Name}>{item.Name}</option>;
                })
            }
        </select>);
    }
});

***Option 3:***
var DropDown = React.createClass(
    {
        render: function () {
            var items = this.props.data;
            return (
            <select>
                {
                    items.map(function (item) {

                                            if (selectedItem == item.Name)
                    return <option value={item.Name } selected>{item.Name}</option>;
                else
                    return <option value={item.Name }>{item.Name}</option>;
                    })
                }
            </select>);
        }
    });
Muthuvel
quelle
1
Obwohl keine Erklärung gegeben wurde, wurde eine nicht wirklich benötigt. Die verschiedenen Möglichkeiten, sich demselben Problem zu nähern, waren wirklich hilfreiche Erkenntnisse. Danke
DJ2
0

Ich hatte ein Problem mit <select>Tags, die nicht korrekt aktualisiert wurden, <option>wenn sich der Status ändert. Mein Problem schien zu sein, dass, wenn Sie zweimal schnell hintereinander rendern, das erste Mal ohne Vorauswahl, <option>aber das zweite Mal mit einem, das <select>Tag beim zweiten Rendern nicht aktualisiert wird, sondern zuerst auf der Standardeinstellung bleibt.

Ich habe eine Lösung dafür mit refs gefunden . Sie müssen einen Verweis auf Ihren <select>Tag-Knoten (der möglicherweise in einer Komponente verschachtelt ist) abrufen und dann die valueEigenschaft im componentDidUpdateHook manuell aktualisieren .

componentDidUpdate(){
  let selectNode = React.findDOMNode(this.refs.selectingComponent.refs.selectTag);
  selectNode.value = this.state.someValue;
}
William Myers
quelle
0

Eine ähnliche Antwort für MULTISELECT / optgroups veröffentlichen:

render() {
  return(
    <div>
      <select defaultValue="1" onChange={(e) => this.props.changeHandler(e.target.value) }>
        <option disabled="disabled" value="1" hidden="hidden">-- Select --</option>
        <optgroup label="Group 1">
          {options1}
        </optgroup>
        <optgroup label="Group 2">
          {options2}
        </optgroup>
      </select>
    </div>
  )
}
daino3
quelle
0

Ich habe eine einfache Lösung, die dem HTML-Grundprinzip folgt.

<input
  type="select"
  defaultValue=""
  >
  <option value="" disabled className="text-hide">Please select</option>
  <option>value1</option>
  <option>value1</option>
</input>

.text-hide ist eine Bootstrap-Klasse. Wenn Sie kein Bootstrap verwenden, sind Sie hier:

.text-hide {
  font: 0/0 a;
  color: transparent;
  text-shadow: none;
  background-color: transparent;
  border: 0;
}
Finn
quelle
-1

Ich habe ein ähnliches Problem umgangen, indem ich defaultProps festgelegt habe:

ComponentName.defaultProps = {
  propName: ''
}

<select value="this.props.propName" ...

Jetzt vermeide ich Fehler beim Kompilieren, wenn meine Requisite erst nach dem Mounten vorhanden ist.

Matt Saunders
quelle
Das löst das Problem wirklich nicht. Sie erhalten Folgendes: Warnung: Fehlgeschlagener Requisitentyp: Sie haben valueeinem Formularfeld ohne onChangeHandler eine Requisite bereitgestellt . Dadurch wird ein schreibgeschütztes Feld gerendert. Wenn das Feld veränderlich sein soll, verwenden Sie defaultValue. Andernfalls stellen Sie entweder onChangeoder ein readOnly.
Jason Rice