React JSX: seçili <seç> seçeneğinde "seçili" seçimi


402

Bir <select>menü için bir React bileşeninde , selectedöznitelik uygulama durumunu yansıtan seçeneği ayarlamak gerekir .

İçinde render(), optionStatedurum sahibinden SortMenu bileşenine iletilir. Seçenek değerleri propsJSON'dan itibaren iletilir .

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

Ancak, bu JSX derlemesinde bir sözdizimi hatası tetikler.

Bunu yapmak sözdizimi hatasından kurtulur, ancak açıkçası sorunu çözmez:

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

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

Ben de denedim:

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

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

Bunu çözmenin önerilen bir yolu var mı?


Sadece başlık için soruyu gözden geçirme
ericgio

Yanıtlar:


648

React, booleanları bu amaçla otomatik olarak anlar, böylece yazabilirsiniz (not: önerilmez)

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

ve uygun şekilde 'seçili' çıktı verecektir.

Ancak, React bunu sizin için daha da kolaylaştırır. selectedHer seçeneği tanımlamak yerine , seçim etiketinin kendisine yazabilirsiniz (ve yazmalısınız)value={optionsState} :

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

Daha fazla bilgi için React select etiketi belgesine bakın .


56
React (0.9) 'un geçerli sürümünde seçeneklerde seçilen öznitelik ayarı hiç çalışmaz. Bunun yerine select öğesinde değer niteliğini ayarlayın.
liammclennan

2
ajax.defaultValue ile veri yüklemek benim için çalışmıyor. değer çalışıyor ama seçim listesinde başka bir öğe seçemiyorum. Liste açılıyor ama bunlardan birini seçtiğimde değer öğesini seçiyorum.
user1924375

5
@ user1924375, onChange olayını kullanmalı onChange={this.handleSelect}ve bileşeniniz için durum değerini ayarlamalısınız, örneğin: 'handleSelect: function () {this.setState ({value: event.target.value});} `Bu, seçtiğiniz bileşeni yeni ile yeniden oluşturur seçilen öğe. Umarım size yardımcı olur.
funnydaredevil

1
Henüz belgelenmemiş olmasına rağmen , etkinleştirilmişse valuea'daki pervane <select>bir dizi olabilir multiselect.
tirdadc

4
defaultValueSıfırlamak için kullanın
dewwwald

70

Şunun "seçili" özelliğini ayarlamaya çalıştığınızda React'ın sizi uyardığı şeyi yapabilirsiniz <option>:

Kullanım defaultValueveya valueüzerinde sahne <select>yerine ayarın selectedüzerine <option>.

Yani, kullanabilirsiniz options.valueüzerinde defaultValuesenin seçme ait


9
Halen seçili olan seçeneği belirtmek istersem bunu nasıl yapabilirim? Şu anda seçeneği seçili tutmanın (ve gelecekteki POSTing için formun durumunu korumanın) tek yolu select = true ayarını yapmaktır. Select öğenin defaultValue ve değer sahne ayarlamayı denedim, ancak bu seçenek menüsünde seçilen doğru seçeneği ayarlayarak görünümünde oluşturmaz. Herhangi bir tavsiye?
Alaca Borular

4
Örnek belki ??
shinzou

1
Benim için çalışmıyor: <select className = "form-control" value = "Mois">
Kuartz

2
defaultValue en yeni sürümle çalışmıyor
Hos Mercury

18

İşte en iyi cevabı ve altındaki yorumları içeren eksiksiz bir çözüm (bu, birisinin hepsini bir araya getirmekte zorluk çekmesine yardımcı olabilir):

ES6 (2019) İÇİN GÜNCELLEME - ok işlevlerini ve nesne yok etmeyi kullanma

ana bileşende:

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

}

dahil bileşen (artık durum bilgisi olmayan bir işlevdir):

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

ÖNCEKİ CEVAP (bağlama kullanarak):

ana bileşende:

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

}

dahil bileşen (artık durum bilgisi olmayan bir işlevdir):

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

ana bileşen meyve için seçilen değeri korur (durumda), dahil edilen bileşen seçme öğesini görüntüler ve güncellemeler durumunu güncellemek için ana bileşene geri aktarılır (daha sonra seçilen değeri değiştirmek için dahil edilen bileşene geri döner).

Türlerine bakılmaksızın aynı formdaki diğer alanlar için tek bir handleChange yöntemi bildirmenize olanak tanıyan bir ad pervane kullanımına dikkat edin.


Yapıcısında hattı Not this.handleChange.bind(this);olmalıdır this.handleChange = this.handleChange.bind(this);
Will Shaver

benim gibi kendilerine ne anlama geldiğini soranlar
talsibony 25:17

@talsibony - bu gerçekten yayılma işleci, ama benim örnek kodda sadece buraya başka bir kod eklemek anlamına gelir !
Andy Lorenz

@AndyLorenz Bu durumda kaldırmanızı tavsiye ederim ... :) ya da // kodunuzun geri kalanı gibi bir yorum yazabilirsiniz
talsibony

8

İşte nasıl yapılacağına dair en son örnek. Gönderen docs tepki artı otomatik bağlanma "şişman-ok" yöntemi sözdizimi.

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

4

Seçtiğiniz etiketin ilk seçeneği olarak eklemeniz yeterlidir:

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

Bu varsayılan olur ve geçerli bir seçenek seçtiğinizde durumunuzda ayarlanır


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

1
Hiçbir açıklama yapılmamasına rağmen, gerçekten gerekli değildi. Aynı soruna yaklaşmanın birçok yolu gerçekten yararlı bir fikirdi. Teşekkürler
DJ2

0

<select>Durum <option>değiştiğinde etiketlerin doğru şekilde güncellenmemesiyle ilgili bir sorun yaşadım . Benim sorunum, iki kez hızlı bir şekilde arka arkaya, önceden seçili olmayan <option>ancak ikinci kez bir tane ile oluşturursanız, <select>etiketin ikinci renderda güncellenmemesi, ancak varsayılan olarak ilk sırada kalması gibi görünüyordu.

Refs kullanarak buna bir çözüm buldum . <select>Etiket düğümünüze (bazı bileşenlerde iç içe yerleştirilmiş olabilecek) bir başvuru almanız ve ardından valueözelliği componentDidUpdatekancada manuel olarak güncellemeniz gerekir .

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

0

MULTISELECT / optgroups için benzer bir cevap göndermek:

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

Basit bir çözüm var HTML temel takip ediyor.

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

.text-hide bir bootstrap sınıfı, eğer bootstrap kullanmıyorsanız, işte buradasınız:

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

-1

Ben defaultProps ayarlayarak benzer bir sorun var:

ComponentName.defaultProps = {
  propName: ''
}

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

Bu yüzden şimdi montaja kadar pervane yoksa derleme hatalarından kaçınırım.


Bu gerçekten problemi çözmüyor. Bunu alırsınız: Uyarı: Başarısız prop türü: valueBir form alanına onChangeişleyici olmayan bir destek sağladınız . Bu, salt okunur bir alanı oluşturur. Alanın değiştirilebilir olması gerekiyorsa kullanın defaultValue. Aksi takdirde, onChangeveya seçeneğini belirleyin readOnly.
Jason Rice,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.