React JSX: sélectionner "sélectionné" sur l'option sélectionnée

Dans un composant React pour un menu <select>, je dois définir l'attribut selected sur l'option qui reflète l'état de l'application.

Dans render(), le optionState est passé du propriétaire de l'état au composant SortMenu. Les valeurs d'option sont transmises sous la forme props à partir de JSON.

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

Cependant, cela déclenche une erreur de syntaxe sur la compilation JSX.

Cela élimine l'erreur de syntaxe mais ne résout évidemment pas le problème:

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

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

J'ai aussi essayé ceci:

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

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

Est y at-il un moyen recommandé de résoudre ce problème?

255
demandé sur Dmitry Shvedov 2014-02-12 20:34:00

10 réponses

Réagir comprend automatiquement les booléens à cette fin, de sorte que vous pouvez simplement écrire (note: non recommandé)

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

Et il affichera' sélectionné ' de manière appropriée.

Cependant, React rend cela encore plus facile pour vous. Au lieu de définir selected sur chaque option, vous pouvez (et devriez) simplement écrire value={optionsState} sur la balise select elle-même :

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

Plus d'infos sur http://facebook.github.io/react/docs/forms.html#why-select-value.

442
répondu Sophie Alpert 2016-03-29 00:03:52

Vous pouvez faire ce que React vous avertit lorsque vous essayez de définir la propriété" selected " du <option>:

Utiliser le defaultValue ou value accessoires sur <select> au lieu de selected sur <option>.

Ainsi, vous pouvez utiliser options.value sur defaultValue de votre select

51
répondu Philippe Santana 2015-04-15 10:20:45

Voici une solution complète qui intègre la meilleure réponse et les commentaires ci-dessous (ce qui pourrait aider quelqu'un qui a du mal à tout rassembler):

Dans le composant principal:

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

}

Composant inclus (qui est maintenant une fonctionnalité sans état):

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

Le composant principal conserve la valeur sélectionnée pour fruit (dans l'état), le composant inclus affiche l'élément select et les mises à jour sont renvoyées au composant principal pour mettre à jour son état (qui revient ensuite en boucle au composant inclus pour modifier la valeur sélectionnée).

Notez l'utilisation d'un prop de nom qui vous permet de déclarer une seule méthode handleChange pour d'autres champs sur le même formulaire quel que soit leur type.

10
répondu Andy Lorenz 2018-01-02 14:10:05
***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>);
        }
    });
2
répondu muthuvel 2016-08-31 13:02:05

J'ai eu un problème avec les balises <select> Ne pas mettre à jour vers le bon <option> lorsque l'état change. Mon problème semblait être que si vous effectuez un rendu deux fois de suite, la première fois sans <option> présélectionné mais la deuxième fois avec un, alors la balise <select> ne se met pas à jour sur le second rendu, mais reste sur la valeur par défaut en premier .

J'ai trouvé une solution à cela en utilisant refs . Vous devez obtenir une référence à votre nœud de balise <select> (qui peut être imbriqué dans un composant), puis mettez à jour manuellement la propriété value sur elle, dans le crochet componentDidUpdate.

componentDidUpdate(){
  let selectNode = React.findDOMNode(this.refs.selectingComponent.refs.selectTag);
  selectNode.value = this.state.someValue;
}
1
répondu William Myers 2015-08-16 07:32:27

Ajoutez Simplement comme première option de votre balise select:

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

Cela deviendra par défaut et lorsque vous sélectionnez une option valide sera définie sur votre état

1
répondu Pietro Allievi 2017-10-27 10:48:28

Poster une réponse similaire pour 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>
  )
}
0
répondu daino3 2017-02-10 16:47:07

Voici le dernier exemple de la façon de le faire , à Partir de réagir 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>
       );
       }
       } 
0
répondu Rahil Ahmad 2018-01-01 16:05:32

J'ai une solution simple suit le HTML de base.

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

.text-hide est la classe d'un bootstrap, si vous n'utilisez pas bootstrap, vous êtes ici:

.text-hide {
  font: 0/0 a;
  color: transparent;
  text-shadow: none;
  background-color: transparent;
  border: 0;
}
0
répondu Finn 2018-03-30 03:10:16

J'ai contourné un problème similaire en définissant defaultProps:

ComponentName.defaultProps = {
  propName: ''
}

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

Alors maintenant j'évite les erreurs sur la compilation si mon accessoire n'existe pas avant le montage.

-2
répondu Matt Saunders 2018-02-25 15:47:44