2014-02-12 9 views
199

In einer React-Komponente für ein <select> Menü muss ich das selected Attribut auf der Option, die den Anwendungsstatus widerspiegelt.Reagieren JSX: Auswahl "ausgewählt" auf <select> Option

In render() wird die optionState vom Statuseigner an die SortMenu-Komponente übergeben. Die Optionswerte werden als props von 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 

Allerdings löst dies einen Syntaxfehler bei der JSX-Kompilierung aus.

diese Weise wird der Syntaxfehler beseitigen, aber offensichtlich das Problem nicht lösen:

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

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

Ich habe auch versucht dies:

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

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

Gibt es eine empfohlene Weg, dies zu lösen?

Antwort

346

automatisch reagieren versteht booleans für diesen Zweck, so können Sie einfach schreiben (Anmerkung: nicht empfohlen)

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

und es wird der Ausgang entsprechend 'ausgewählt'.

React macht dies jedoch noch einfacher für Sie. Statt selected auf jede Option definiert, können (und sollten) einfach schreiben value={optionsState} auf dem select-Tag selbst:

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

Mehr Infos unter http://facebook.github.io/react/docs/forms.html#why-select-value.

+28

Mit der aktuellen Version von React (0.9) Einstellung funktioniert das ausgewählte Attribut auf Optionen überhaupt nicht. Setzen Sie stattdessen das value-Attribut auf das select-Element. – liammclennan

+4

+1 für die Freigabe des Werts = {OptionState}, nette kleine Trick. –

+0

Können Sie Objekt übergeben oder nur Zeichenfolge Wert? –

48

Sie tun konnte, was React warnt Sie, wenn Sie versuchen, die „ausgewählt“ Eigenschaft des <option> einzustellen:

Verwenden Sie die defaultValue oder value Requisiten auf <select> statt selected auf <option> der Einstellung.

So können Sie options.value auf der defaultValue Ihrer select

+8

zu initialisieren Wenn ich immer noch die Option anzeigen möchte, die derzeit ausgewählt ist, wie würde ich dies tun?Die einzige Möglichkeit, die Option aktuell auszuwählen (und den Status des Formulars für zukünftige POST-Vorgänge beizubehalten), besteht in der Einstellung von select = true. Ich habe versucht, die defaultValue- und value-Requisiten des select-Elements zu setzen, aber dies wird nicht in der Ansicht gerendert, indem die richtige Option im Optionsmenü ausgewählt wird. Irgendein Rat? –

1

ich ein Problem habe verwenden mit <select> Tags nicht auf die richtige <option> aktualisieren, wenn sich der Zustand ändert. Mein Problem schien zu sein, dass, wenn Sie zweimal in schneller Folge, das erste Mal ohne Vorwahl <option> aber das zweite Mal mit einem, dann das <select> Tag nicht auf dem zweiten Render aktualisieren, aber auf dem Standard zuerst bleibt.

Ich fand eine Lösung mit refs. Sie müssen einen Verweis auf Ihren <select> Tag-Knoten erhalten (der in einer Komponente verschachtelt sein könnte) und dann die value-Eigenschaft manuell aktualisieren, und zwar im componentDidUpdate Hook.

componentDidUpdate(){ 
    let selectNode = React.findDOMNode(this.refs.selectingComponent.refs.selectTag); 
    selectNode.value = this.state.someValue; 
} 
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>); 
     } 
    }); 
0

für eine ähnliche Antwort Veröffentlichung MULTISELECT/optgroups:

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

ist die komplette Lösung, die die beste Antwort und die Kommentare unten, damit er enthält (was jemand helfen könnte kämpfen, es zu Stück alle zusammen):

in 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} onChange{this.handleChange} /> 
    ) 
    } 

} 

enthalten Komponente (die nun eine zustandslose funktionsfähig 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 hält den ausgewählten Wert für die Früchte (in Zustand), zeigt der enthaltenen Komponente das Auswahlelement und Aktualisierungen werden an die Hauptzurückgeleitet Komponente, um ihren Status zu aktualisieren (der dann zu der enthaltenen Komponente zurückkehrt, um den ausgewählten Wert zu ändern).

Beachten Sie die Verwendung eines Namensrequisitors, mit dem Sie unabhängig vom Typ eine einzige handleChange-Methode für andere Felder auf demselben Formular deklarieren können.

+0

Beachten Sie die Zeile im Konstruktor 'this.handleChange.bind (this);' sollte 'this.handleChange = this.handleChange.bind (this)' sein; –

+0

guten Platz @WillShaver! Fest. –

+0

für diejenigen von euch wie mich, die sich selbst fragen, was die ... bedeutet: https://reactjs.org/docs/jsx-in-depth.html#spread-attributes – talsibony

0

Fügen Sie einfach als erste Option Ihrer select-Tag:

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

Dieser Standard werden wird und wenn Sie eine gültige Option wählen wird

0

Hier auf Ihrem Zustand setted ist das jüngste Beispiel für wie es zu tun, von react docs

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

     this.handleChange = this.handleChange.bind(this); 
     this.handleSubmit = this.handleSubmit.bind(this); 
     } 

     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 La Croix 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> 
     ); 
     } 
     } 
-1

ich durch das Setzen defaultProps um ein ähnliches Problem habe:

ComponentName.defaultProps = { 
    propName: '' 
} 

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

So, jetzt vermeide ich Fehler auf Kompilierung, wenn meine Stütze nicht existiert, bis Montag.

Verwandte Themen