Bereaksi JSX: memilih "terpilih" pada opsi <select> yang dipilih

403

Dalam komponen Bereaksi untuk <select>menu, saya perlu mengatur selectedatribut pada opsi yang mencerminkan keadaan aplikasi.

Di render(), optionStatediteruskan dari pemilik negara ke komponen SortMenu. Nilai opsi diteruskan sebagai propsdari 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

Namun itu memicu kesalahan sintaks pada kompilasi JSX.

Melakukan hal ini akan menghilangkan kesalahan sintaksis tetapi jelas tidak menyelesaikan masalah:

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

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

Saya juga mencoba ini:

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

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

Apakah ada cara yang disarankan untuk menyelesaikan ini?

cantera
sumber
Mengajukan pertanyaan hanya untuk judul
ericgio

Jawaban:

649

Bereaksi secara otomatis memahami boolean untuk tujuan ini, jadi Anda cukup menulis (catatan: tidak disarankan)

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

dan itu akan menampilkan 'dipilih' dengan tepat.

Namun, Bereaksi membuat ini lebih mudah bagi Anda. Alih-alih mendefinisikan selectedpada setiap opsi, Anda dapat (dan seharusnya) cukup menulis value={optionsState}pada tag pilih itu sendiri :

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

Untuk info lebih lanjut, lihat Bereaksi pilih tag doc .

Sophie Alpert
sumber
56
Dengan versi React (0.9) saat ini mengatur atribut yang dipilih pada opsi tidak bekerja sama sekali. Tetapkan atribut nilai pada elemen pilih sebagai gantinya.
liammclennan
2
saya memuat data dengan ajax.defaultValue tidak berfungsi untuk saya. nilai berfungsi tetapi saya tidak dapat memilih item lain pada daftar pilih. Daftar membuka tetapi ketika saya memilih salah satu dari mereka pilih nilai item. Setiap ide?
user1924375
5
@ user1924375 Anda harus menggunakan onChange event onChange={this.handleSelect}dan menetapkan nilai status untuk komponen Anda, misalnya: 'handleSelect: function () {this.setState ({value: event.target.value});} `Ini akan membuat komponen pilih Anda dengan yang baru item yang dipilih. Semoga ini bisa membantu Anda.
funnydaredevil
1
Meskipun belum didokumentasikan, valueprop pada a <select>dapat berupa array jika Anda telah multiselectmengaktifkan.
tirdadc
4
Agak digunakan defaultValueuntuk menginisialisasi
dewwwald
70

Anda dapat melakukan apa yang Bereaksi memperingatkan Anda ketika Anda mencoba mengatur properti "terpilih" dari <option>:

Gunakan defaultValueatau valuealat peraga pada <select>bukannya pengaturan selectedaktif <option>.

Jadi, Anda dapat menggunakan options.valuepada pilihan defaultValueAnda

Philippe Santana
sumber
9
Jika saya ingin tetap menunjukkan opsi yang saat ini dipilih, bagaimana saya melakukannya? Satu-satunya cara saya saat ini dapat benar-benar menjaga pilihan tetap dipilih (dan menjaga status formulir untuk POSTing di masa depan) adalah dengan menetapkan select = true. Saya telah mencoba mengatur nilai Default dan alat peraga nilai dari elemen pilih, tetapi ini tidak membuat tampilan dengan mengatur opsi yang benar untuk dipilih dalam menu opsi. Ada saran?
The Pied Pipes
4
Contoh mungkin ??
shinzou
1
Tidak berfungsi untuk saya: <select className = "form-control" value = "Mois">
Kuartz
2
defaultValue tidak berfungsi dengan versi terbaru
Hos Mercury
18

Berikut ini adalah solusi lengkap yang menggabungkan jawaban terbaik dan komentar di bawahnya (yang mungkin membantu seseorang yang kesulitan untuk menyatukan semuanya):

UPDATE FOR ES6 (2019) - menggunakan fungsi panah dan perusakan objek

dalam komponen utama:

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

}

termasuk komponen (yang sekarang menjadi fungsional stateless):

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

JAWABAN SEBELUMNYA (menggunakan ikatan):

dalam komponen utama:

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

}

termasuk komponen (yang sekarang menjadi fungsional stateless):

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

komponen utama mempertahankan nilai yang dipilih untuk buah (dalam keadaan), komponen yang disertakan menampilkan elemen yang dipilih dan pembaruan dikembalikan ke komponen utama untuk memperbarui keadaannya (yang kemudian memutar kembali ke komponen yang disertakan untuk mengubah nilai yang dipilih).

Perhatikan penggunaan prop nama yang memungkinkan Anda untuk mendeklarasikan metode handleChange tunggal untuk bidang lain pada formulir yang sama terlepas dari jenisnya.

Andy Lorenz
sumber
Perhatikan garis di konstruktor this.handleChange.bind(this);harus this.handleChange = this.handleChange.bind(this);
Will Shaver
bagi anda seperti saya yang bertanya kepada mereka sendiri apa ... artinya: reactjs.org/docs/jsx-in-depth.html#spread-attributes
talsibony
@talsibony - itu memang operator penyebaran, tetapi dalam kode sampel saya itu hanya berarti memasukkan beberapa kode lain di sini !
Andy Lorenz
@AndyLorenz Jadi dalam hal ini saya akan merekomendasikan untuk menghapusnya ... :), atau hanya menulis komentar seperti // sisa kode Anda
talsibony
8

Berikut ini contoh terbaru cara melakukannya. Dari bereaksi docs , ditambah sintaks metode "lemak-panah" yang mengikat secara otomatis.

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
sumber
4

Cukup tambahkan sebagai opsi pertama dari tag pilihan Anda:

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

Ini akan menjadi default dan ketika Anda akan memilih opsi yang valid akan ditetapkan pada negara Anda

Pietro Allievi
sumber
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
sumber
1
Meskipun tidak ada penjelasan yang diberikan, namun sebenarnya tidak diperlukan. Berbagai cara untuk mendekati masalah yang sama sangat membantu wawasan. Terima kasih
DJ2
0

Saya punya masalah dengan <select>tag yang tidak diperbarui ke yang benar <option>ketika kondisi berubah. Masalah saya tampaknya adalah bahwa jika Anda membuat dua kali berturut-turut, pertama kali tanpa pra-pilih <option>tetapi kedua kalinya dengan satu, maka <select>tag tidak memperbarui pada render kedua, tetapi tetap pada default pertama.

Saya menemukan solusi untuk ini menggunakan referensi . Anda perlu mendapatkan referensi ke <select>simpul tag Anda (yang mungkin bersarang di beberapa komponen), dan kemudian secara manual memperbarui valueproperti di dalamnya, di componentDidUpdatehook.

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

Posting jawaban yang serupa untuk 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>
  )
}
Daino3
sumber
0

Saya punya solusi sederhana mengikuti dasar HTML.

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

.text-hide adalah kelas bootstrap, jika Anda tidak menggunakan bootstrap, inilah Anda:

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

Saya mengatasi masalah serupa dengan mengatur defaultProps:

ComponentName.defaultProps = {
  propName: ''
}

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

Jadi sekarang saya menghindari kesalahan pada kompilasi jika prop saya tidak ada sampai pemasangan.

Matt Saunders
sumber
Itu benar-benar tidak menyelesaikan masalah. Anda akan mendapatkan ini: Peringatan: Jenis penyangga gagal: Anda memberikan valuepenyangga ke bidang formulir tanpa onChangepenangan. Ini akan membuat bidang hanya baca. Jika bidang harus dapat digunakan berubah-ubah defaultValue. Jika tidak, atur salah satu onChangeatau readOnly.
Jason Rice